使用XMLHttpRequest发送POST数据

我想在JavaScript中使用XMLHttpRequest发送一些数据。

假设我在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编写等效内容?

1563704 次浏览

下面的代码演示了如何做到这一点。

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]));
}
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来提交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>

讲话

  1. 这并没有完全回答OP问题,因为它需要用户单击才能提交请求。但这可能对寻找这种简单解决方案的人有用。

  2. 这个例子非常简单,不支持GET方法。如果您对更复杂的示例感兴趣,请查看优秀的MDN文档。参见类似的答案关于XMLHttpRequest Post HTML表单

  3. 该解决方案的局限性:正如Justin BlankThomas Munk(见他们的评论)所指出的那样,FormData在IE9及以下版本和Android 2.3的默认浏览器中不支持。

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");
}

不需要插件!

选择下面的代码并将其拖到书签栏 (如果你没有看到它,从浏览器设置启用),然后是编辑链接:

enter image description here

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);

现在你可以访问任何网站,点击按钮在书签栏!


注意:

上面的方法使用XMLHttpRequest方法发送数据,因此,在触发脚本时,您必须在同一个域中。这就是为什么我更喜欢用模拟表单提交发送数据,它可以将代码发送到任何域-这里是为此编写的代码:

 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);

我也遇到过类似的问题,使用相同的帖子和这个链接,我已经解决了我的问题。

 var http = new XMLHttpRequest();
var url = "MY_URL.Com/login.aspx";
var params = 'eid=' +userEmailId+'&amp;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);

这个链接已经完成了信息。

使用现代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 Documentation .

Can I Use (96% Nov 2020)

David Walsh Tutorial

这里是一个完整的解决方案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>

确保你的后端API可以解析JSON。

例如,在Express JS中:

import bodyParser from 'body-parser'
app.use(bodyParser.json())

只是为了让专题读者发现这个问题。我发现,只要你有一个给定的路径,接受的答案就可以工作,但如果你让它为空,它将在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);
})

有一些重复的作品涉及到这一点,但没有人真正阐述它。我将借用公认答案的例子来说明

http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');

为了说明,我过于简化了这个问题(我使用http.onload(function() {})而不是那个答案的旧方法)。如果你按原样使用,你会发现你的服务器可能会将POST正文解释为一个字符串,而不是实际的key=value参数(即PHP不会显示任何$_POST变量)。你必须传递表单头来获得它,并在http.send()之前这样做

http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

如果您使用的是JSON而不是url编码的数据,则应该传递application/json

这帮助我,因为我想只使用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/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

尝试使用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);
}
}

短,现代

可以捕获表单输入值使用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>