backup_restore.htm 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <div class="cbi-value" id="_backup_div">
  2. <label class="cbi-value-title"><%:Create Backup File%></label>
  3. <div class="cbi-value-field">
  4. <input class="btn cbi-button cbi-button-save" type="button" onclick="dl_backup()" value="<%:DL Backup%>" />
  5. </div>
  6. </div>
  7. <div class="cbi-value" id="_upload_div">
  8. <label class="cbi-value-title"><%:Restore Backup File%></label>
  9. <div class="cbi-value-field">
  10. <input class="btn cbi-button cbi-button-apply" type="button" id="upload-btn" value="<%:RST Backup%>" />
  11. </div>
  12. </div>
  13. <div class="cbi-value" id="_reset_div">
  14. <label class="cbi-value-title"><%:Restore to default configuration%></label>
  15. <div class="cbi-value-field">
  16. <input class="btn cbi-button cbi-button-remove" type="button" onclick="do_reset()" value="<%:Do Reset%>" />
  17. </div>
  18. </div>
  19. <div id="upload-modal" class="up-modal" style="display:none;">
  20. <div class="up-modal-content">
  21. <h3><%:Restore Backup File%></h3>
  22. <div class="cbi-value" id="_upload_div">
  23. <div class="up-cbi-value-field">
  24. <input class="cbi-input-file" type="file" id="ulfile" name="ulfile" accept=".tar.gz" required />
  25. <br />
  26. <div class="up-button-container">
  27. <input class="btn cbi-button cbi-button-apply" type="submit" value="<%:UL Restore%>" />
  28. <input class="btn cbi-button cbi-button-remove" type="button" id="upload-close" value="<%:CLOSE WIN%>" />
  29. </div>
  30. </div>
  31. </div>
  32. </div>
  33. </div>
  34. <style>
  35. .up-modal {
  36. position: fixed;
  37. left: 50%;
  38. top: 50%;
  39. transform: translate(-50%, -50%);
  40. background: white;
  41. padding: 20px;
  42. border: 2px solid #ccc;
  43. box-shadow: 0 0 10px rgba(0,0,0,0.5);
  44. z-index: 1000;
  45. }
  46. .up-modal-content {
  47. width: 100%;
  48. max-width: 400px;
  49. text-align: center;
  50. display: flex;
  51. flex-direction: column;
  52. justify-content: center;
  53. align-items: center;
  54. }
  55. .up-button-container {
  56. display: flex;
  57. justify-content: space-between;
  58. width: 100%;
  59. max-width: 250px;
  60. }
  61. .up-cbi-value-field {
  62. display: flex;
  63. flex-direction: column;
  64. align-items: center;
  65. width: 100%;
  66. }
  67. </style>
  68. <script>
  69. // JavaScript 版本的 url 函数
  70. function url(...args) {
  71. let url = "/cgi-bin/luci/admin/services/shadowsocksr";
  72. for (let i = 0; i < args.length; i++) {
  73. if (args[i] !== "") {
  74. url += "/" + args[i];
  75. }
  76. }
  77. return url;
  78. }
  79. // 上传按钮点击事件
  80. document.getElementById("upload-btn").addEventListener("click", function() {
  81. document.getElementById("upload-modal").style.display = "block";
  82. });
  83. // 关闭上传模态框
  84. document.getElementById("upload-close").addEventListener("click", function() {
  85. document.getElementById("upload-modal").style.display = "none";
  86. });
  87. // 备份下载函数
  88. function dl_backup(btn) {
  89. fetch(url("backup"), { // 使用 JavaScript 版本的 url 函数
  90. method: 'POST',
  91. credentials: 'same-origin'
  92. })
  93. .then(response => {
  94. if (!response.ok) {
  95. throw new Error("备份失败!");
  96. }
  97. const filename = response.headers.get("X-Backup-Filename");
  98. if (!filename) {
  99. return;
  100. }
  101. return response.blob().then(blob => ({ blob, filename }));
  102. })
  103. .then(result => {
  104. if (!result) return;
  105. const { blob, filename } = result;
  106. const url = window.URL.createObjectURL(blob);
  107. const a = document.createElement("a");
  108. a.href = url;
  109. a.download = filename;
  110. document.body.appendChild(a);
  111. a.click();
  112. a.remove();
  113. window.URL.revokeObjectURL(url);
  114. })
  115. .catch(error => alert(error.message));
  116. }
  117. // 恢复出厂设置
  118. function do_reset(btn) {
  119. if (confirm("<%: Do you want to restore the client to default settings?%>")) {
  120. setTimeout(function () {
  121. if (confirm("<%: Are you sure you want to restore the client to default settings?%>")) {
  122. // 清理日志
  123. var xhr1 = new XMLHttpRequest();
  124. xhr1.open("GET", url("clear_log"), true); // 使用 JavaScript 版本的 url 函数
  125. xhr1.send();
  126. // 恢复出厂
  127. var xhr2 = new XMLHttpRequest();
  128. xhr2.open("GET", url("reset"), true); // 使用 JavaScript 版本的 url 函数
  129. xhr2.send();
  130. // 处理响应
  131. xhr2.onload = function() {
  132. if (xhr2.status === 200) {
  133. window.location.href = url("reset");
  134. }
  135. };
  136. }
  137. }, 1000);
  138. }
  139. }
  140. </script>