使用XMLHttpRequest发送POST数据


526

我想使用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编写等效项?

Answers:


748

下面的代码演示了如何执行此操作。

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

46
是否可以发送对象params而不是像jQuery中的字符串?
Vadorequest 2014年

4
不,但是@Vadorequest的评论中提到了jQuery-他询问是否可以“像jQuery”那样传递数据。我提到了我认为jQuery如何做到这一点,以及如何实现这一目标。
丹·潘特里

11
@EdHeal,Connection并且Content-Length无法设置标题。它会说“拒绝设置不安全的标头“ content-length””。参见stackoverflow.com/a/2624167/632951
Pacerier,2015年

76
注意:open()之后的 setRequestHeader ()。花了我一个小时,希望这个评论可以为一个人节省一个小时;)
凯文(Kevin

4
是否可以发送application/json请求?

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

4
FormData将form元素作为其构造函数参数,无需单独添加值
Juan Mendes

6
是的,但问题是编写与提供的表单等效的JavaScript,而不使用JavaScript提交表单。
uKolka 2013年

3
票数少但被标记为正确的答案使用两个额外的标题:http.setRequestHeader("Content-length", params.length);http.setRequestHeader("Connection", "close");。他们需要吗?也许仅某些浏览器才需要它们?(在另一页上有一条评论说,设置Content-Length标头是“完全需要”)
Darren Cook

@Darren Cook实施依赖。根据我的经验,主要浏览器会根据您提供的数据自动设置“内容长度”(必填)。在大多数情况下,“连接”标头默认情况下为“保持活动”,这会使连接保持打开状态一段时间,因此后续请求不必像“关闭”时一样重新建立连接。您可以使用当前页面的URL在控制台中尝试这些片段,并使用浏览器的工具或wirehark检查请求标头。
uKolka 2013年

4
@uKolka应该在回复中注明,而不是第二种解决方案,请求Content-Type会自动更改为multipart/form-data。这对服务器端以及如何在其中访问信息产生了严重影响。
AxeEffect

84

使用现代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年3月95%)

David Walsh教程


4
您应该避免对网页功能至关重要的事情使用Promises和粗箭头,因为许多设备没有支持这些功能的浏览器。
德米特里(Dmitry)

8
承诺已覆盖90%。我添加了function()一些示例,以防您不喜欢=>。您绝对应该使用现代JS来简化开发人员的体验。除非您是一个庞大的企业,否则担心一小部分被IE困扰的人是不值得的
Gibolt

4
粗箭头也不适用于this关键字。我喜欢提及这一点,但我也暗中讨厌使用this,继承体系结构而不是函数工厂的人们。原谅我,我是节点。
agm1984年

3
我也避免this像瘟疫一样,任何人都应该阅读this
Gibolt

2
如果担心兼容性...谷歌ES6 transpiler ... stackoverflow.com/questions/40205547/...。写得简单。兼容部署。+1避免this
TamusJRoyce

35

最少使用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到HTML表单的类似答案

  3. 此解决方案的局限性:正如Justin BlankThomas Munk(请参阅他们的评论)所指出的那样,FormDataIE9及更低版本以及Android 2.3上的默认浏览器均不支持该解决方案。


1
唯一的问题是,我认为FormData在IE 9中不可用,因此对于没有polyfill的许多人来说,它将无法使用。developer.mozilla.org/zh-CN/docs/Web/API/FormData
贾斯汀·布朗克

感谢@ThomasMunk提供的链接:-)我们看到FormDataIE9和Android 2.3(和OperaMini,但最后一种并未得到广泛使用)支持的许多浏览器都支持。干杯;-)
olibre

2
优雅的解决方案,但是您应该指定onsubmit="return submitForm(this);"否则用户将被重定向到请求中的URL。
2015年

感谢@Vic的贡献,我已经更新了答案。干杯;-)
olibre 2015年

1
我对网络开发的经验不足。我已经知道POST请求确实在您返回时发送false。如果true返回,将发送原始(不需要的)POST请求!您的回答是正确的,对于您的困惑,我们深表歉意。
Markus L

30

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

1
很好,但是不要对XMLHttpRequest.open中的async参数使用'false'值-已过时,它将发出警告
johnnycardy

我们应该在此处正确设置还是忽略该参数?如果您可以指定哪个更合适,我将更新答案。
agm1984 '18

1
它应该默认为true,但我不知道所有浏览器是否都遵守
johnnycardy

给定默认的true,我将从示例中删除它,并删除以下URL进行研究:developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/open
agm1984 '18

1
我比较喜欢这种方式,因为这是合理的,而对于某人来说,细节就少了。感谢您突出显示它。
agm1984 '18

25

无需插件!

选择以下代码并将其拖到“ 书签栏”中如果看不到,请从“浏览器设置”中启用),然后编辑该链接:

在此处输入图片说明

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,我可以做类似的事情吗?

我没有,我也没有:| 我没有125次代表:| 如果您看到我的个人资料,就会看到我有136票赞成:| 即使获得许可,我也将避免使用它,除非有必要:|

18
您的问题确实无法回答OP的要求。为HTTP请求添加书签...!?我看不出XmlHttpRequest您的答案有任何意义:|

2
太棒了 我只是想在复习时有一些关系,因为这是一个答案。现在,这是一个答案,并为所有来访者提供gr8提示。我已恢复投票。欢呼声
Iceman

5

我使用相同的帖子也遇到了类似的问题,并且此链接已经解决了我的问题。

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

链接具有完整的信息。


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

1
您好雨果,如果浏览器支持,此代码用于发送带有进度上传的数据或文件。包括所有可能的事件和兼容性浏览器。它尝试使用浏览器中最新的对象类。有帮助吗?
托托

2

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

1

仅适用于功能读者发现此问题。我发现只要您具有给定的路径,可接受的答案就可以正常工作,但是如果将其保留为空白,则它将在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);
})

1

有一些重复的内容,没有人真正地阐述过。我将借用可接受的答案示例进行说明

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改为传递


1

这对我有所帮助,因为我只想使用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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.