HTML表单通过AJAX向localhost:8000/api发送JSON数据失败求助
无法向localhost:8000/api发送JSON格式的表单数据
尝试约三小时,参考多篇Stack Overflow帖子,仍无法实现HTML表单向localhost:8000/api服务器发送JSON数据。点击提交按钮后,Firefox开发者工具Network标签无交互记录,始终触发错误函数。
原代码
<!DOCTYPE html> <html lang="en"> <head> <title>API Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form id="input_form" action="" method="post"> <input type="text" placeholder="Name" name="fullName"> <input type="button" value="Submit" id="submit"> </form> <script> $("#submit").on('click', function(){ $.ajax({ url: 'localhost:8000/api', type : "POST", data: JSON.stringify($("form")), dataType : 'json', contentType: 'application/json', success : function(result) { console.log(result); console.log("It works") }, error: function(xhr, resp, text) { console.log("Did not work") console.log(xhr, resp, text); } }) }); </script> </body> </html>
编辑1:Firefox控制台输出
[NoScript]:0 Prompt Hook installation file:///C:/html/Quiz/username.htm log.js:32:13 Freezing file:///C:/html/Quiz/username.htm DocumentFreezer.js:101:15 Unfreezing file:///C:/html/Quiz/username.htm DocumentFreezer.js:117:15 Diese Seite verwendet die nicht standardisierte Eigenschaft "zoom". Stattdessen sollte calc() in den entsprechenden Eigenschaftswerten oder "transform" zusammen mit "transform-origin: 0 0" verwendet werden. username.htm Did not work username.htm:33:29 Object { readyState: 0, getResponseHeader: getResponseHeader(e), getAllResponseHeaders: getAllResponseHeaders(), setRequestHeader: setRequestHeader(e, t), overrideMimeType: overrideMimeType(e), statusCode: statusCode(e), abort: abort(e), state: state(), always: always(), catch: catch(e) , … } abort: function abort(e) always: function always() catch: function catch(e) done: function add() fail: function add() getAllResponseHeaders: function getAllResponseHeaders() getResponseHeader: function getResponseHeader(e) overrideMimeType: function overrideMimeType(e) pipe: function pipe() progress: function add() promise: function promise(e) readyState: 0 responseJSON: undefined setRequestHeader: function setRequestHeader(e, t) state: function state() status: 0 statusCode: function statusCode(e) statusText: "error" then: function then(t, n, r) <prototype>: Object { … } error <empty string> username.htm:34:14
编辑2:表单序列化错误
错误源头来自这一行:
data: JSON.stringify($("form")),
执行console.log(JSON.stringify($("form")))得到冗余结果(关键部分):
{"0":{"0":{},"1":{"jQuery363081041549224722111":{"events":{"click":[{"type":"click","origType":"click","guid":15,"namespace":""}]}}}},"length":1,"prevObject":{"0":{"location":{"href":"file:///C:/html/Quiz/username.htm","origin":"null","protocol":"file:","host":"","hostname":"","port":"","pathname":"/C:/html/Quiz/username.htm","search":"","hash":""},"jQuery363081041549224722111":{"events":{"click":[...]},"focusout":[...],"focusin":[...],"keydown":[...]}},"length":1}}
编辑3:直接发送JSON对象也失败
即使使用硬编码的JSON对象,请求仍失败:
$("#submit").on('click', function(){ const input_data = {name: "John", age: 30, city: "New York"}; $.ajax({ url: 'localhost:8000', type : "POST", dataType : 'json', data: input_data, contentType: 'application/json;charset=UTF-8', success : function(result) { console.log(result); console.log("It works") }, error: function(xhr, resp, text) { console.log("Did not work") console.log(xhr, resp, text); } }) });
控制台输出:
Object { readyState: 0, getResponseHeader: getResponseHeader(e), getAllResponseHeaders: getAllResponseHeaders(), setRequestHeader: setRequestHeader(e, t), overrideMimeType: overrideMimeType(e), statusCode: statusCode(e), abort: abort(e), state: state(), always: always(), catch: catch(e) , … } error <empty string>
解决方案
1. 修正URL协议问题
直接写localhost:8000/api会被浏览器当作当前file://协议的相对路径,必须添加http://前缀,改为http://localhost:8000/api。
2. 正确转换表单数据为JSON
JSON.stringify($("form"))序列化的是jQuery表单DOM对象,而非用户输入。需要提取表单字段值并组装成JSON对象:
function formToJson(formSelector) { const formData = $(formSelector).serializeArray(); const jsonObj = {}; formData.forEach(item => { jsonObj[item.name] = item.value; }); return jsonObj; }
3. 发送正确格式的JSON数据
设置contentType: 'application/json'时,必须将数据转为JSON字符串,不能直接传JavaScript对象(jQuery默认会将对象转为x-www-form-urlencoded格式,与contentType冲突)。
完整修正代码
<!DOCTYPE html> <html lang="en"> <head> <title>API Example</title> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.6.3/jquery.min.js"></script> <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.4.1/js/bootstrap.min.js"></script> </head> <body> <form id="input_form" action="" method="post"> <input type="text" placeholder="Name" name="fullName"> <input type="button" value="Submit" id="submit"> </form> <script> // 表单转JSON工具函数 function formToJson(formSelector) { const formData = $(formSelector).serializeArray(); const jsonObj = {}; formData.forEach(item => { jsonObj[item.name] = item.value; }); return jsonObj; } $("#submit").on('click', function(){ const formJson = formToJson("#input_form"); $.ajax({ url: 'http://localhost:8000/api', type : "POST", data: JSON.stringify(formJson), dataType : 'json', contentType: 'application/json;charset=UTF-8', success : function(result) { console.log(result); console.log("It works") }, error: function(xhr, resp, text) { console.log("Did not work") console.log(xhr, resp, text); } }) }); </script> </body> </html>
内容的提问来源于stack exchange,提问作者tonispark
相关产品推荐
相关产品推荐

