[Feature][S300][task-view-993][webui] add web upload upgrade package upgrade function

Change-Id: I4507582b3757791e21bae800968c843b3f8c82fe
diff --git a/lynq/CPE_COMMON/ap/app/cgi/cgi.c b/lynq/CPE_COMMON/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/CPE_COMMON/ap/app/cgi/cgi.c
+++ b/lynq/CPE_COMMON/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
index aee7cab..66bd038 100755
--- a/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1104,6 +1104,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1430,6 +1431,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 8a741d7..cac2e65 100755
--- a/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/CPE_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1106,6 +1106,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1436,6 +1437,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/CPE_COMMON/ap/app/zte_webui/subpg/ota_update.html b/lynq/CPE_COMMON/ap/app/zte_webui/subpg/ota_update.html
index 9a0f935..7cf5ca6 100755
--- a/lynq/CPE_COMMON/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/CPE_COMMON/ap/app/zte_webui/subpg/ota_update.html
@@ -138,11 +138,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -181,6 +182,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -192,4 +194,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/CPE_TELKOMSEL/ap/app/cgi/cgi.c b/lynq/CPE_TELKOMSEL/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/CPE_TELKOMSEL/ap/app/cgi/cgi.c
+++ b/lynq/CPE_TELKOMSEL/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_en.properties
index 63571bb..5f397e3 100755
--- a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1095,6 +1095,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1422,6 +1423,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index d542aa7..d8df30c 100755
--- a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1097,6 +1097,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1428,6 +1429,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/subpg/ota_update.html b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/subpg/ota_update.html
index 0eaf819..5ecbaf6 100755
--- a/lynq/CPE_TELKOMSEL/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/CPE_TELKOMSEL/ap/app/zte_webui/subpg/ota_update.html
@@ -138,11 +138,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -181,6 +182,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -192,4 +194,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/MD310/ap/app/cgi/cgi.c b/lynq/MD310/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/MD310/ap/app/cgi/cgi.c
+++ b/lynq/MD310/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/MD310/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/MD310/ap/app/zte_webui/i18n/Messages_en.properties
index 11e6913..5bd1c7c 100755
--- a/lynq/MD310/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/MD310/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1109,6 +1109,7 @@
 fota_package_no_new_version = No new version detected

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1436,6 +1437,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/MD310/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/MD310/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 45564f1..618bd46 100755
--- a/lynq/MD310/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/MD310/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1111,6 +1111,7 @@
 fota_package_no_new_version = 没有检测到新版本

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1442,6 +1443,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/MD310/ap/app/zte_webui/subpg/ota_update.html b/lynq/MD310/ap/app/zte_webui/subpg/ota_update.html
index d9c3d63..26cc24b 100755
--- a/lynq/MD310/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/MD310/ap/app/zte_webui/subpg/ota_update.html
@@ -146,11 +146,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -189,6 +190,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -200,4 +202,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/R306/ap/app/cgi/cgi.c b/lynq/R306/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/R306/ap/app/cgi/cgi.c
+++ b/lynq/R306/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/R306/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/R306/ap/app/zte_webui/i18n/Messages_en.properties
index 91a2790..3cf26c4 100755
--- a/lynq/R306/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/R306/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1095,6 +1095,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1421,6 +1422,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/R306/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/R306/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 8194604..c780a79 100755
--- a/lynq/R306/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/R306/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1097,6 +1097,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1427,6 +1428,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/R306/ap/app/zte_webui/subpg/ota_update.html b/lynq/R306/ap/app/zte_webui/subpg/ota_update.html
index 0eaf819..5ecbaf6 100755
--- a/lynq/R306/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/R306/ap/app/zte_webui/subpg/ota_update.html
@@ -138,11 +138,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -181,6 +182,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -192,4 +194,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/R307/ap/app/cgi/cgi.c b/lynq/R307/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/R307/ap/app/cgi/cgi.c
+++ b/lynq/R307/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
index d225280..e14252b 100755
--- a/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/R307/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1106,6 +1106,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1433,6 +1434,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 9fc91d9..57f4050 100755
--- a/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/R307/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1108,6 +1108,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1439,6 +1440,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/R307/ap/app/zte_webui/subpg/ota_update.html b/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
index c1a34ef..0fd9102 100755
--- a/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/R307/ap/app/zte_webui/subpg/ota_update.html
@@ -137,11 +137,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -180,6 +181,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -191,4 +193,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/S300/ap/app/cgi/cgi.c b/lynq/S300/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/S300/ap/app/cgi/cgi.c
+++ b/lynq/S300/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/S300/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/S300/ap/app/zte_webui/i18n/Messages_en.properties
index 6a50372..6331edf 100755
--- a/lynq/S300/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/S300/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1104,6 +1104,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1430,6 +1431,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/S300/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/S300/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index 083d6cb..1a84811 100755
--- a/lynq/S300/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/S300/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1106,6 +1106,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1436,6 +1437,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/S300/ap/app/zte_webui/subpg/ota_update.html b/lynq/S300/ap/app/zte_webui/subpg/ota_update.html
index 0eaf819..5ecbaf6 100755
--- a/lynq/S300/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/S300/ap/app/zte_webui/subpg/ota_update.html
@@ -138,11 +138,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -181,6 +182,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -192,4 +194,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file
diff --git a/lynq/S300_COMMON/ap/app/cgi/cgi.c b/lynq/S300_COMMON/ap/app/cgi/cgi.c
index 3aaddd0..7583edb 100755
--- a/lynq/S300_COMMON/ap/app/cgi/cgi.c
+++ b/lynq/S300_COMMON/ap/app/cgi/cgi.c
@@ -277,51 +277,32 @@
 	return 0;

 }

 

+static void print_json_response(int success, const char* message)

+{

+    printf("Content-type: application/json\r\n\r\n");

+    printf("{\"success\": %d, \"message\": \"%s\"}\n", success, message);

+}

+

 static void cgi_fota_update_progress()

 {

     int upgradeStatus, result;

 

     system("fota_upi -u verify > /dev/null 2>&1");

-	result = fota_get_update_status(&upgradeStatus);

-	if(result < 0)

-	{

-        printf("<h1 style='color: red;'>Error: Fail to read update file!</h1>");

-	}

-	else if(upgradeStatus != 0)

-	{

-		printf("<h1 style='color: red;'>Error: Verify update file failed!</h1>");

-	}

-	else

-	{

-		printf("<h1 style='color: green;'>File verification successful, start updating...</h1>");

-		system("fota_upi -u recovery &");

-	}

-}

-

-static void html_print_start()

-{

-    printf("Content-type: text/html\r\n\r\n");

-    printf("<!DOCTYPE html>\n");

-    printf("<html lang=\"en\">\n");

-    printf("<head>\n");

-    printf("<meta charset=\"UTF-8\">\n");

-    printf("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n");

-    printf("<title>File Upload Status</title>\n");

-    printf("<style>\n");

-    printf("body { font-family: Arial, sans-serif; background-color: #f4f4f4; margin: 0; padding: 0; padding-top: 20px; }\n");

-    printf(".container { background-color: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 10px rgba(0, 0, 0, 0.1); text-align: center; width: 80%%; max-width: 500px; margin: 0 auto; }\n");

-    printf("h1 { margin: 10px 0; }\n");

-    printf("</style>\n");

-    printf("</head>\n");

-    printf("<body>\n");

-    printf("<div class=\"container\">\n");    

-}

-

-static void html_print_end()

-{

-    printf("</div>\n");

-    printf("</body>\n");

-    printf("</html>\n");

+    result = fota_get_update_status(&upgradeStatus);

+    if(result < 0)

+    {

+        print_json_response(0, "Fail to read update file");

+    }

+    else if(upgradeStatus != 0)

+    {

+        print_json_response(0, "Verify update file failed");

+    }

+    else

+    {

+        print_json_response(1, "File verification successful, start updating...");

+        sleep(1);

+        system("fota_upi -u recovery > /dev/null 2>&1 &");

+    }

 }

 

 int main()

@@ -338,35 +319,28 @@
     content_length_str = getenv("CONTENT_LENGTH");

     if (!content_length_str)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Missing CONTENT_LENGTH environment variable</h1>");

+        print_json_response(0, "Missing CONTENT_LENGTH environment variable");

         return 1;

     }

 

     content_length = atoi(content_length_str);

     if (content_length <= 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: Invalid CONTENT_LENGTH</h1>");

+        print_json_response(0, "Invalid CONTENT_LENGTH");

         return 1;

     }

 

     // Call the file upload handling function

     if (handle_file_upload(source_filename, target_filename, content_length) != 0)

     {

-        printf("Content-type: text/html\r\n\r\n");

-        printf("<h1>Error: File upload failed</h1>");

+        print_json_response(0, "File upload failed");

         return 1;

     }

 

     // Output success information

-    html_print_start();

-    printf("<h1 style='color: green;'>File upload successful!</h1>");

-    //printf("<p>The file has been saved to %s</p>", target_filename);

+    //print_json_response(1, "File upload successful");

 

     cgi_fota_update_progress();

 

-    html_print_end();

-

     return 0;

 }

diff --git a/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_en.properties b/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
index 451f73b..3d6e981 100755
--- a/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
+++ b/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_en.properties
@@ -1104,6 +1104,7 @@
 ota_manual_upgrade_url = Upgrade File Download Address 

 fota_package_already_download = Upgrade package has been downloaded,after waiting for equipment to restart to complete.

 software_upload = Software Upload

+local_upload = Local Upgrade

 upload_update_success = The upgrade file upload successful and will be about to restart,do not power off.

 upload_update_failed0 = parse file failed.   

 upload_update_failed1 = verify file failed.   

@@ -1430,6 +1431,10 @@
 upgrade_pack_fix_success = Upgrade success!

 upgrade_pack_fix_failed = Upgrade failed!

 have_new_version = New version is found,the device will update.

+upload_file = File upload in progress!

+update_status_error = Fail to read the update status file, unable to update!

+verify_error = Verification upgrade file failed, unable to update!

+start_update = The upgrade file has been successfully verified and is currently being upgraded. Please do not power off, restore factory settings, or shut down the device!

 

 ######key same value different###########

 dmz_note_info = If a terminal device can''t run network applications via this device, please enter IP address of the terminal device in the entry box when DMZ is enabled.

diff --git a/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties b/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
index dd5fc0d..ef29419 100755
--- a/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
+++ b/lynq/S300_COMMON/ap/app/zte_webui/i18n/Messages_zh-cn.properties
@@ -1106,6 +1106,7 @@
 ota_manual_upgrade_url = 升级文件下载地址

 fota_package_already_download = 升级包已下载,待设备重启后完成升级

 software_upload = 软件升级

+local_upload = 本地升级

 upload_update_success = 升级文件上传成功,即将重启,请勿断电。

 upload_update_failed0 = 文件解析失败。   

 upload_update_failed1 = 文件校验失败。   

@@ -1436,6 +1437,11 @@
 upgrade_pack_fix_success = 升级成功!

 upgrade_pack_fix_failed = 升级失败!

 have_new_version = 发现新版本,设备将升级。

+upload_file = 文件上传中!

+update_status_error = 获取更新状态文件失败,无法升级!

+verify_error = 校验文件失败,无法升级!

+start_update = 校验升级文件成功,正在升级中,请不要断电、恢复出厂设置或关机!

+

 ######key same value different###########

 dmz_note_info = 如果终端设备无法通过该设备运行网络应用程序,请启用 DMZ,在输入框输入该终端设备的 IP 地址。

 dlna_note_info = DLNA: 数字生活网络联盟。

diff --git a/lynq/S300_COMMON/ap/app/zte_webui/subpg/ota_update.html b/lynq/S300_COMMON/ap/app/zte_webui/subpg/ota_update.html
index 0eaf819..5ecbaf6 100755
--- a/lynq/S300_COMMON/ap/app/zte_webui/subpg/ota_update.html
+++ b/lynq/S300_COMMON/ap/app/zte_webui/subpg/ota_update.html
@@ -138,11 +138,12 @@
 

 

 <br><br>

-<form action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+<form id="uploadForm" action="../../cgi-bin/upload/upload.cgi" method="post" enctype="multipart/form-data">

+	<h3 class="form-title" data-trans="local_upload"></h3>

     <div class="row form-group col-xs-4 side-right">

         <label for="fileInput" data-trans="software_upload" style="display: none;"></label>

         <input class="required form-control btn btn-primary" type="file" id="fileInput" name="file" style="display: none;">

-        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" stylewidth=": 150px;"></label>

+        <label for="fileInput" class="required btn btn-primary" data-trans="browse_btn" style="width: 70px;"></label>

         <span id="fileNameDisplay" style="margin-left: 10px; font-weight: normal;"></span>

     </div>

     <br><br>

@@ -181,6 +182,7 @@
     const fileInput = document.getElementById('fileInput');

     const fileNameDisplay = document.getElementById('fileNameDisplay');

     const submitButton = document.getElementById('submitButton');

+    const uploadForm = document.getElementById('uploadForm');

 

     fileInput.addEventListener('change', function () {

         const fileName = fileInput.files[0] ? fileInput.files[0].name : '';

@@ -192,4 +194,44 @@
             submitButton.disabled = true;

         }

     });

+

+    // 阻止表单提交的默认行为

+	uploadForm.addEventListener('submit', function (event) {

+		event.preventDefault(); // 阻止默认提交行为

+		showLoading("upload_file");

+

+		const formData = new FormData(uploadForm);

+		console.log("Form data submitted:", formData);

+

+		fetch(uploadForm.action, {

+			method: 'POST',

+			body: formData

+		})

+		.then(response => {

+			if (!response.ok) {

+				throw new Error(`HTTP error! Status: ${response.status}`);

+			}

+			return response.text(); // 先获取原始文本

+		})

+		.then(text => {

+			console.log("Server response:", text); // 打印服务器返回的内容

+			try {

+				const data = JSON.parse(text); // 尝试解析为JSON

+				if (data.success) {

+					//alert("File upload successful: " + data.message);

+					showAlert("start_update");

+				} else {

+					//alert("File upload successful: " + data.message);

+					errorOverlay("verify_error");

+				}

+			} catch (error) {

+				console.error("Upload error:", error);

+				errorOverlay("File upload successful: Server returned non-JSON response.");

+			}

+		})

+		.catch(error => {

+			console.error("Upload error:", error);

+			errorOverlay("File upload failed!");

+		});

+	});

 </script>
\ No newline at end of file