使用XMLHttpRequest发送POST数据

Jac*_*ill 487 javascript ajax post xmlhttprequest

我想在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>
Run Code Online (Sandbox Code Playgroud)

如何在JavaScript中使用XMLHttpRequest编写等效代码?

Ed *_*eal 696

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

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);
Run Code Online (Sandbox Code Playgroud)

  • 注意:**open()之后的setRequestHeader()**.花了我一个小时,让我们希望这个评论可以节省一个小时;) (64认同)
  • 是否可以在`params`中发送一个对象而不是像jQuery中的字符串? (40认同)
  • @EdHeal,`Connection`和`Content-Length`标题无法设置.它会说"拒绝设置不安全的标题"内容长度"".请参见http://stackoverflow.com/a/2624167/632951 (11认同)
  • 不,但是@Vadorequest的评论提到了jQuery - 他问是否有可能传递数据"像jQuery".我提到了我认为jQuery如何做到这一点,因此,你如何实现这一目标. (4认同)
  • 是否可以发送`application/json`请求? (4认同)
  • 您应该能够设置任何自定义内容类型,只要您的服务器知道如何解释它。 (2认同)
  • 还值得注意的是 `setRequestHeader` 中的第三个参数,它需要一个 bool 来确定请求是否被缓存...如果结果被缓存,这可能会导致严重的头痛,因为进一步的请求将失败 (2认同)
  • 并且....您需要对参数进行JSON.stringify(),否则它将在后端抛出无效的JSON错误。 (2认同)
  • http.open方法中的true参数指定每个[w3school链接](https://www.w3schools.com/xml/dom_httprequest.asp)的同步性。最好编写类似const async = true的代码;http.open(...,异步);` (2认同)
  • application / x-www-form-urlencoded告诉服务器期望提交的数据是url编码的。答案中的值(“ ipsum”和“ binny”)不包含任何需要编码的字符,但是如果这样做,则可以使用encodeURIComponent('value')完成。例如,`encodeURIComponent('this&that')`将返回`this%26that`。否则,服务器会将“&”解释为界定下一个key = value对。 (2认同)

uKo*_*lka 252

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');
Run Code Online (Sandbox Code Playgroud)

或者,如果您可以依赖浏览器支持,则可以使用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);
Run Code Online (Sandbox Code Playgroud)

  • 是的,但问题是编写JavaScript等效的提供表单而不是使用JavaScript提交表单. (5认同)
  • FormData将form元素作为其构造函数参数,无需单独添加值 (3认同)
  • 得票少但标记正确的答案使用了两个额外的标题:`http.setRequestHeader("Content-length",params.length);`和`http.setRequestHeader("Connection","close");`.他们需要吗?它们可能只在某些浏览器上需要吗?(在其他页面上有评论说设置Content-Length标题是"完全需要的") (3认同)
  • @uKolka应该在回复时注明,而不是第二个解决方案,请求`Content-Type`自动更改为`multipart/form-data`.这对服务器端以及如何在那里访问信息具有严重影响. (3认同)

Gib*_*olt 66

使用现代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)
);
Run Code Online (Sandbox Code Playgroud)

更多信息:

Mozilla文档

我可以使用(2018年3月88日)

马特沃尔什教程

  • [承诺](https://caniuse.com/#feat=promises)覆盖率为90%.如果您不喜欢[`=>`](https://caniuse.com/#feat=arrow-functions),我添加了`function()`示例.您绝对应该使用现代JS来减轻开发人员的体验.除非你是一个庞大的企业,否则担心只有一小部分人坚持使用IE浏览器是不值得的 (5认同)
  • 胖箭头也不适用于`this`关键字.我想提一下,但我也暗中讨厌使用`this`和继承架构而不是函数工厂的人.原谅我,我是节点. (4认同)
  • 我也像瘟疫那样避免"这个",所以读"这个"的人也应如此. (3认同)
  • 对于对网页功能至关重要的事情,您应该避免使用Promises和fat箭头,因为许多设备没有支持这些功能的浏览器. (2认同)
  • 如果担心兼容性... Google es6 transpiler ... /sf/ask/2814388321/。写得简单。兼容部署。+1避免使用“ this”。 (2认同)
  • 什么?避免使用“this”,因为我**无法**理解它?卡帕。 (2认同)
  • 同步示例是错误的,它不应该在“await”之后使用“then”,您可以立即访问变量中的内容。如果您想要检查,则需要一个“try-catch”块。 (2认同)

oli*_*bre 32

最少使用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>
Run Code Online (Sandbox Code Playgroud)

备注

  1. 这并不完全回答OP问题,因为它要求用户单击以提交请求.但这对于寻找这种简单解决方案的人来说可能是有用的.

  2. 此示例非常简单,不支持该GET方法.如果您对更复杂的示例感兴趣,请查看优秀的MDN文档.另请参阅关于XMLHttpRequest到Post HTML Form的类似答案.

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

  • 优雅的解决方案,但你应该指定`onsubmit ="return submitForm(this);"`否则用户将被重定向到请求中的URL. (2认同)

agm*_*984 28

这是一个完整的解决方案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>
Run Code Online (Sandbox Code Playgroud)

确保您的Backend API可以解析JSON.

例如,在Express JS中:

import bodyParser from 'body-parser'
app.use(bodyParser.json())
Run Code Online (Sandbox Code Playgroud)


T.T*_*dua 26

不需要插件!

只需在BOOKMARK BAR中拖动任何链接(即此链接)(如果您没有看到它,从浏览器设置启用),然后编辑该链接:

在此输入图像描述

并插入javascript代码:

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);
Run Code Online (Sandbox Code Playgroud)

就这样!现在您可以访问任何网站,然后单击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); 
Run Code Online (Sandbox Code Playgroud)

  • 而你的问题确实没有回答OP的要求.BookMarking HTTP请求......!?我在你的回答中没有看到任何关于`XmlHttpRequest`的观点:| (15认同)
  • 真棒.只是想要一些关系,同时审查,因为它是一个答案.现在这是一个答案加上一个gr8提示给所有谁.我已经退回了选票.干杯 (2认同)

小智 7

尝试使用 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 我相信应该在调用“send”之前分配“onreadystatechange”。 (3认同)

tot*_*oto 5

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");
}
Run Code Online (Sandbox Code Playgroud)


Lax*_*n G 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);
Run Code Online (Sandbox Code Playgroud)

链接具有完整的信息。


Mac*_*ity 5

有一些重复涉及到这一点,但没有人真正详细说明。我将借用公认的答案示例来说明

http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');
Run Code Online (Sandbox Code Playgroud)

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

http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
Run Code Online (Sandbox Code Playgroud)

如果您使用的是 JSON 而不是 URL 编码的数据,请application/json改为传递