说我在HTML中具有以下形式:
<form name="inputform" action="somewhere" method="post">
<input type="hidden" value="person" name="user">
<input type="hidden" value="password" name="pwd">
<input type="hidden" value="place" name="organization">
<input type="hidden" value="key" name="requiredkey">
</form>
如何使用JavaScript中的XMLHttpRequest编写等效项?
#1 楼
下面的代码演示了如何执行此操作。var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);
//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
http.onreadystatechange = function() {//Call a function when the state changes.
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
如果拥有/创建对象,则可以使用以下代码将其转换为参数:
var params = new Object();
params.myparam1 = myval1;
params.myparam2 = myval2;
// Turn the data object into an array of URL-encoded key/value pairs.
let urlEncodedData = "", urlEncodedDataPairs = [], name;
for( name in params ) {
urlEncodedDataPairs.push(encodeURIComponent(name)+'='+encodeURIComponent(params[name]));
}
评论
是否可以使用params发送对象而不是像jQuery中的字符串发送对象?
–Vadorequest
2014年9月7日上午11:27
不,但是@Vadorequest的评论中提到了jQuery-他问是否可以“像jQuery”那样传递数据。我提到了我认为jQuery如何做到这一点,以及如何实现这一目标。
–丹
2015年4月16日14:33
无法设置@ EdHeal,Connection和Content-Length标头。它会说“拒绝设置不安全的标头“ content-length””。见stackoverflow.com/a/2624167/632951
–起搏器
15年6月27日在10:55
注意:open()之后的setRequestHeader()。花了我一个小时,让我们希望此评论可以节省一个小时的时间;)
–凯文
16-09-26在8:30
是否可以发送应用程序/ json请求?
–user6516765
16 Dec 6'在3:03
#2 楼
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send('user=person&pwd=password&organization=place&requiredkey=key');
或者如果您可以依靠浏览器支持,则可以使用FormData:
var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
// do something to response
console.log(this.responseText);
};
xhr.send(data);
评论
FormData将form元素作为其构造函数参数,无需单独添加值
–胡安·门德斯(Juan Mendes)
13年6月22日在5:51
是的,但问题是编写与提供的表单等效的JavaScript,而不使用JavaScript提交表单。
– uKolka
13年6月22日在17:07
投票很少但被标记为正确的答案使用两个额外的标题:http.setRequestHeader(“ Content-length”,params.length);和http.setRequestHeader(“ Connection”,“ close”);。他们需要吗?也许仅某些浏览器才需要它们? (在另一页上有一条评论说,设置Content-Length标头是“完全需要”)
–达伦·库克(Darren Cook)
2013年10月17日在0:19
@Darren Cook实施依赖。根据我的经验,主要浏览器会根据您提供的数据自动设置“内容长度”(必填)。在大多数情况下,“连接”标头默认情况下为“保持活动”,这会使连接保持打开状态一段时间,因此后续请求不必像“关闭”时一样重新建立连接。您可以使用当前页面的URL在控制台中尝试这些片段,并使用浏览器的工具或Wireshark检查请求标头。
– uKolka
13-10-18在0:46
@uKolka应该在回复中注明,而不是第二种解决方案,即请求Content-Type自动更改为multipart / form-data。这对服务器端以及如何在其中访问信息产生了严重影响。
– AxeEffect
17年7月10日在9:29
#3 楼
使用现代JavaScript!建议您考虑一下
fetch
。它等效于ES5,并使用Promises。它更具可读性且易于自定义。 const url = "http://example.com";
fetch(url, {
method : "POST",
body: new FormData(document.getElementById("inputform")),
// -- or --
// body : JSON.stringify({
// user : document.getElementById('user').value,
// ...
// })
}).then(
response => response.text() // .json(), etc.
// same as function(response) {return response.text();}
).then(
html => console.log(html)
);
在Node.js中,您需要使用以下命令导入
fetch
:const fetch = require("node-fetch");
如果要同步使用(不适用于顶级范围):
const json = await fetch(url, optionalOptions)
.then(response => response.json()) // .text(), etc.
.catch((e) => {});
更多信息:
Mozilla文档
我可以使用(2020年11月96%)
大卫·沃尔什教程
评论
对于许多对网页功能至关重要的事情,您应该避免使用Promises和粗箭头,因为许多设备没有支持这些功能的浏览器。
–德米特里
17年9月2日在13:30
承诺已覆盖90%。我添加了function()示例,以防您不喜欢=>。您绝对应该使用现代JS来简化开发人员的体验。除非您是一个庞大的企业,否则担心一小部分被IE困扰的人是不值得的
–Gibolt
17-09-2在20:06
粗箭头也不适用于此关键字。我喜欢提及这一点,但我也暗中讨厌使用此功能的人,并讨厌继承体系结构而不是函数工厂。原谅我,我是节点。
–agm1984
17年9月8日在9:17
我也像瘟疫一样避免这种情况,任何人都应该阅读。
–Gibolt
17-10-20在17:28
如果担心兼容性... Google es6 transpiler ... stackoverflow.com/questions/40205547 /...。写得简单。兼容部署。 +1避免这种情况。
– TamusJRoyce
17-12-27 17:25
#4 楼
最少使用FormData
提交AJAX请求<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
var xhr = new XMLHttpRequest();
xhr.onload = function(){ alert (xhr.responseText); } // success case
xhr.onerror = function(){ alert (xhr.responseText); } // failure case
xhr.open (oFormElement.method, oFormElement.action, true);
xhr.send (new FormData (oFormElement));
return false;
}
</script>
</head>
<body>
<form method="post" action="somewhere" onsubmit="return submitForm(this);">
<input type="hidden" value="person" name="user" />
<input type="hidden" value="password" name="pwd" />
<input type="hidden" value="place" name="organization" />
<input type="hidden" value="key" name="requiredkey" />
<input type="submit" value="post request"/>
</form>
</body>
</html>
备注
这不能完全回答OP问题,因为它需要用户单击以提交请求。但这对于寻找这种简单解决方案的人们可能有用。
此示例非常简单,不支持
GET
方法。如果您对更复杂的示例感兴趣,请查看出色的MDN文档。另请参见有关将XMLHttpRequest发布到HTML表单的类似答案。此解决方案的模仿:正如Justin Blank和Thomas Munk(请参阅他们的评论)所指出的,IE43及更低版本的IE9不支持
FormData
,而Android 2.3上则是默认浏览器。 评论
唯一的问题是,我认为FormData在IE 9中不可用,因此对于没有polyfill的许多人来说,它将无法使用。 developer.mozilla.org/zh-CN/docs/Web/API/FormData
–贾斯汀·布兰克(Justin Blank)
2014年7月9日14:19
感谢@ThomasMunk提供的链接:-)我们看到FormIE支持除IE9和Android 2.3(以及OperaMini,但最后一种并未广泛使用)之外的许多浏览器。干杯;-)
– oHo
14-10-24在7:56
#5 楼
这是使用application-json
的完整解决方案: // Input values will be grabbed by ID
<input id="loginEmail" type="text" name="email" placeholder="Email">
<input id="loginPassword" type="password" name="password" placeholder="Password">
// return stops normal action and runs login()
<button onclick="return login()">Submit</button>
<script>
function login() {
// Form fields, see IDs above
const params = {
email: document.querySelector('#loginEmail').value,
password: document.querySelector('#loginPassword').value
}
const http = new XMLHttpRequest()
http.open('POST', '/login')
http.setRequestHeader('Content-type', 'application/json')
http.send(JSON.stringify(params)) // Make sure to stringify
http.onload = function() {
// Do whatever with response
alert(http.responseText)
}
}
</script>
请确保您的Backend API可以解析JSON。例如,在Express JS中:
import bodyParser from 'body-parser'
app.use(bodyParser.json())
评论
很好,但是不要对XMLHttpRequest.open中的async参数使用'false'值-已过时,它将发出警告
– johnnycardy
18-3-23在15:29
我们应该在此处正确设置还是忽略该参数?如果您可以指定哪个更合适,我将更新答案。
–agm1984
18年4月16日在19:56
它应该默认为true,但我不知道所有浏览器是否都尊重
– johnnycardy
18年4月17日在8:58
给定默认的true,我将从示例中将其删除,并删除以下URL以供研究:developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open
–agm1984
18年4月17日在19:09
我比较喜欢这种方式,因为这很合理,一开始的细节也很少。感谢您突出显示它。
–agm1984
18年4月17日在19:11
#6 楼
无需插件!选择以下代码并将其拖入“书签栏”(如果看不到,请从“浏览器设置”中启用),然后编辑该链接:
javascript:var my_params = prompt("Enter your parameters", "var1=aaaa&var2=bbbbb"); var Target_LINK = prompt("Enter destination", location.href); function post(path, params) { var xForm = document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } var xhr = new XMLHttpRequest(); xhr.onload = function () { alert(xhr.responseText); }; xhr.open(xForm.method, xForm.action, true); xhr.send(new FormData(xForm)); return false; } parsed_params = {}; my_params.split("&").forEach(function (item) { var s = item.split("="), k = s[0], v = s[1]; parsed_params[k] = v; }); post(Target_LINK, parsed_params); void(0);
就这些!现在,您可以访问任何网站,然后在BOOKMARK BAR中单击该按钮!
注意:
上述方法使用
XMLHttpRequest
方法发送数据,因此,触发脚本时必须位于同一域中。这就是为什么我更喜欢使用模拟的FORM SUBMITTING发送数据,该表单可以将代码发送到任何域-这是该代码: javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) { var xForm= document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); xForm.setAttribute("target", "_blank"); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } document.body.appendChild(xForm); xForm.submit(); } parsed_params={}; my_params.split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0);
评论
对于Mozilla,我可以做类似的事情吗?
–user6538026
16年7月29日在5:46
我没有,我也没有:|我没有125次代表:|如果您看到我的个人资料,就会看到我有136票赞成:|即使获得许可,我也将避免使用它,除非有必要:|
–user6538026
16年7月29日在9:20
您的问题确实无法回答OP的要求。为HTTP请求添加书签...!?在您的答案中,我看不到与XmlHttpRequest相关的任何内容:|
–user6538026
16年7月29日在9:27
太棒了我只是想在复习时有一些关系,因为这是一个答案。现在,这是一个答案,并为所有来访者提供gr8提示。我已恢复投票。干杯
–冰人
16年8月19日在11:06
#7 楼
我使用相同的帖子也遇到了类似的问题,并且此链接已经解决了我的问题。 var http = new XMLHttpRequest();
var url = "MY_URL.Com/login.aspx";
var params = 'eid=' +userEmailId+'&pwd='+userPwd
http.open("POST", url, true);
// Send the proper header information along with the request
//http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
//http.setRequestHeader("Content-Length", params.length);// all browser wont support Refused to set unsafe header "Content-Length"
//http.setRequestHeader("Connection", "close");//Refused to set unsafe header "Connection"
// Call a function when the state
http.onreadystatechange = function() {
if(http.readyState == 4 && http.status == 200) {
alert(http.responseText);
}
}
http.send(params);
此链接具有完整的信息。
#8 楼
var util = {
getAttribute: function (dom, attr) {
if (dom.getAttribute !== undefined) {
return dom.getAttribute(attr);
} else if (dom[attr] !== undefined) {
return dom[attr];
} else {
return null;
}
},
addEvent: function (obj, evtName, func) {
//Primero revisar attributos si existe o no.
if (obj.addEventListener) {
obj.addEventListener(evtName, func, false);
} else if (obj.attachEvent) {
obj.attachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = func;
} else {
obj[evtName] = func;
}
}
},
removeEvent: function (obj, evtName, func) {
if (obj.removeEventListener) {
obj.removeEventListener(evtName, func, false);
} else if (obj.detachEvent) {
obj.detachEvent(evtName, func);
} else {
if (this.getAttribute("on" + evtName) !== undefined) {
obj["on" + evtName] = null;
} else {
obj[evtName] = null;
}
}
},
getAjaxObject: function () {
var xhttp = null;
//XDomainRequest
if ("XMLHttpRequest" in window) {
xhttp = new XMLHttpRequest();
} else {
// code for IE6, IE5
xhttp = new ActiveXObject("Microsoft.XMLHTTP");
}
return xhttp;
}
};
//START CODE HERE.
var xhr = util.getAjaxObject();
var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));
if (isUpload) {
util.addEvent(xhr, "progress", xhrEvt.onProgress());
util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart);
util.addEvent(xhr, "abort", xhrEvt.onAbort);
}
util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState);
var xhrEvt = {
onProgress: function (e) {
if (e.lengthComputable) {
//Loaded bytes.
var cLoaded = e.loaded;
}
},
onLoadStart: function () {
},
onAbort: function () {
},
onReadyState: function () {
var state = xhr.readyState;
var httpStatus = xhr.status;
if (state === 4 && httpStatus === 200) {
//Completed success.
var data = xhr.responseText;
}
}
};
//CONTINUE YOUR CODE HERE.
xhr.open('POST', 'mypage.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
if ('FormData' in window) {
var formData = new FormData();
formData.append("user", "aaaaa");
formData.append("pass", "bbbbb");
xhr.send(formData);
} else {
xhr.send("?user=aaaaa&pass=bbbbb");
}
评论
您好雨果,如果浏览器支持,此代码用于发送带有进度上传的数据或文件。包括所有可能的事件和兼容性浏览器。它尝试使用浏览器中最新的对象类。有帮助吗?
–toto
16 Dec 8'在17:24
#9 楼
有一些重复的内容,没有人真正地阐述过。我将借用公认的答案示例进行说明http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');
为了说明起见,我对此进行了简化(我使用
http.onload(function() {})
代替了该答案的旧方法)。如果按原样使用,则会发现服务器可能将POST主体解释为字符串,而不是实际的key=value
参数(即,PHP将不会显示任何$_POST
变量)。您必须传递表单标题才能实现此目的,并在http.send()
之前执行此操作。 br />#10 楼
这对我有帮助,因为我只想使用xmlHttpRequest
并将对象作为表单数据发布:function sendData(data) {
var XHR = new XMLHttpRequest();
var FD = new FormData();
// Push our data into our FormData object
for(name in data) {
FD.append(name, data[name]);
}
// Set up our request
XHR.open('POST', 'https://example.com/cors.php');
// Send our FormData object; HTTP headers are set automatically
XHR.send(FD);
}
https://developer.mozilla.org/zh-CN/docs / Learn / HTML / Forms / Sending_forms_through_JavaScript
#11 楼
尝试使用json对象代替formdata。以下是对我有用的代码。 formdata也不适合我,因此我想出了这个解决方案。var jdata = new Object();
jdata.level = levelVal; // level is key and levelVal is value
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://MyURL", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(jdata));
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
console.log(this.responseText);
}
}
评论
我相信onreadystatechange应该在调用send之前分配。
–内森·莫因瓦济里(Nathan Moinvaziri)
8月13日下午1:01
#12 楼
仅适用于功能读者发现此问题。我发现,只要您具有给定的路径,可接受的答案就可以正常工作,但是如果将其保留为空白,则它将在IE中失败。这是我想出的:function post(path, data, callback) {
"use strict";
var request = new XMLHttpRequest();
if (path === "") {
path = "/";
}
request.open('POST', path, true);
request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
request.onload = function (d) {
callback(d.currentTarget.response);
};
request.send(serialize(data));
}
你可以这样:
post("", {orem: ipsum, name: binny}, function (response) {
console.log(respone);
})
#13 楼
简短现代您可以使用FormData捕获表单输入值,并通过提取发送它们。
fetch(form.action, {method:'post', body: new FormData(form)});
function send() {
let form = document.forms['inputform'];
fetch(form.action, {method:'post', body: new FormData(form)});
}
<form name="inputform" action="somewhere" method="post">
<input value="person" name="user">
<input type="hidden" value="password" name="pwd">
<input value="place" name="organization">
<input type="hidden" value="key" name="requiredkey">
</form>
<!-- I remove type="hidden" for some inputs above only for show them --><br>
Look: chrome console>network and click <button onclick="send()">send</button>
评论
来自developer.mozilla.org的示例:developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest / ...