JavaScript提交请求,如表单提交

我试图将浏览器导向到不同的页面。 如果我想要一个GET请求,我可能会说

document.location.href = 'http://example.com/q=a'; 

但是我试图访问的资源将不会正确响应,除非我使用POST请求。 如果这不是dynamic生成的,我可以使用HTML

 <form action="http://example.com/" method="POST"> <input type="hidden" name="q" value="a"> </form> 

然后,我只需从DOM提交表单。

但是,我真的想要JavaScript代码,让我说

 post_to_url('http://example.com/', {'q':'a'}); 

什么是最好的跨浏览器实现?

编辑

对不起,我不清楚。 我需要一个改变浏览器位置的解决scheme,就像提交表单一样。 如果这可能与XMLHttpRequest ,这是不明显的。 这不应该是asynchronous的,也不要使用XML,所以Ajax不是答案。

 function post(path, params, method) { method = method || "post"; // Set method to post by default if not specified. // The rest of this code assumes you are not using a library. // It can be made less wordy if you use one. var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", path); for(var key in params) { if(params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } } document.body.appendChild(form); form.submit(); } 

例:

 post('/contact/', {name: 'Johnny Bravo'}); 

编辑 :由于这已经得到upvoted这么多,我猜人们会复制粘贴这很多。 所以我添加了hasOwnProperty检查来修复任何无意的错误。

这将是使用jQuery所选答案的一个版本。

 // Post to the provided URL with the specified parameters. function post(path, parameters) { var form = $('<form></form>'); form.attr("method", "post"); form.attr("action", path); $.each(parameters, function(key, value) { var field = $('<input></input>'); field.attr("type", "hidden"); field.attr("name", key); field.attr("value", value); form.append(field); }); // The form needs to be a part of the document in // order for us to be able to submit it. $(document.body).append(form); form.submit(); } 

@Aaron的一个简单的快速和肮脏的实现答案:

 document.body.innerHTML += '<form id="dynForm" action="http://example.com/" method="post"><input type="hidden" name="q" value="a"></form>'; document.getElementById("dynForm").submit(); 

当然,你应该使用一个JavaScript框架,如Prototype或jQuery …

使用在这个答案中提供的createElement函数,这是由于IE的破坏与正常使用document.createElement创build的元素上的name属性所必需的:

 function postToURL(url, values) { values = values || {}; var form = createElement("form", {action: url, method: "POST", style: "display: none"}); for (var property in values) { if (values.hasOwnProperty(property)) { var value = values[property]; if (value instanceof Array) { for (var i = 0, l = value.length; i < l; i++) { form.appendChild(createElement("input", {type: "hidden", name: property, value: value[i]})); } } else { form.appendChild(createElement("input", {type: "hidden", name: property, value: value})); } } } document.body.appendChild(form); form.submit(); document.body.removeChild(form); } 

Rakesh Pai的回答是惊人的,但是当您尝试使用名为submit的字段发布表单时,我发现了一个问题(在Safari中 )。 例如, post_to_url("http://google.com/",{ submit: "submit" } ); 。 我已经修补了这个函数来绕过这个variables空间的碰撞。

  function post_to_url(path, params, method) { method = method || "post"; var form = document.createElement("form"); //Move the submit function to another variable //so that it doesn't get overwritten. form._submit_function_ = form.submit; form.setAttribute("method", method); form.setAttribute("action", path); for(var key in params) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); form.appendChild(hiddenField); } document.body.appendChild(form); form._submit_function_(); //Call the renamed function. } post_to_url("http://google.com/", { submit: "submit" } ); //Works! 

如果你已经安装了Prototype ,你可以加紧代码来生成并提交隐藏的表单,如下所示:

  var form = new Element('form', {method: 'post', action: 'http://example.com/'}); form.insert(new Element('input', {name: 'q', value: 'a', type: 'hidden'})); $(document.body).insert(form); form.submit(); 

不,你不能像提交表单一样提交JavaScript发布请求。

你可以拥有一个HTML格式的表单,然后用JavaScript提交。 (正如本页多次解释的那样)

您可以自己创buildHTML,不需要JavaScript来编写HTML。 如果有人提出这样的话,那将是愚蠢的。

 <form id="ninja" action="http://example.com/" method="POST"> <input id="donaldduck" type="hidden" name="q" value="a"> </form> 

你的函数只是按照你想要的方式来configuration表单。

 function postToURL(a,b,c){ document.getElementById("ninja").action = a; document.getElementById("donaldduck").name = b; document.getElementById("donaldduck").value = c; document.getElementById("ninja").submit(); } 

然后,像使用它。

 postToURL("http://example.com/","q","a"); 

但是我只是忽略这个function而已。

  document.getElementById('donaldduck').value = "a"; document.getElementById("ninja").submit(); 

最后,风格决定进入ccs文件。

 .ninja{ display:none; } 

我个人认为forms应该用名字来解决,但现在并不重要。

这是rakesh的答案,但支持数组(这在表单中很常见):

纯javascript:

 function post_to_url(path, params, method) { method = method || "post"; // Set method to post by default, if not specified. // The rest of this code assumes you are not using a library. // It can be made less wordy if you use one. var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", path); var addField = function( key, value ){ var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", value ); form.appendChild(hiddenField); }; for(var key in params) { if(params.hasOwnProperty(key)) { if( params[key] instanceof Array ){ for(var i = 0; i < params[key].length; i++){ addField( key, params[key][i] ) } } else{ addField( key, params[key] ); } } } document.body.appendChild(form); form.submit(); } 

哦,这里的jQuery版本:(略有不同的代码,但归结为相同的东西)

 function post_to_url(path, params, method) { method = method || "post"; // Set method to post by default, if not specified. var form = $(document.createElement( "form" )) .attr( {"method": method, "action": path} ); $.each( params, function(key,value){ $.each( value instanceof Array? value : [value], function(i,val){ $(document.createElement("input")) .attr({ "type": "hidden", "name": key, "value": val }) .appendTo( form ); }); } ); form.appendTo( document.body ).submit(); } 

那么,希望我已经读过所有其他的post,所以我没有浪费时间从Rakesh Pai的回答中创build这个。 这是一个适用于数组和对象的recursion解决scheme。 没有依赖jQuery。

添加一个段来处理整个表单应该像数组一样提交的情况。 (即在项目列表周围没有包装对象的地方)

 /** * Posts javascript data to a url using form.submit(). * Note: Handles json and arrays. * @param {string} path - url where the data should be sent. * @param {string} data - data as javascript object (JSON). * @param {object} options -- optional attributes * { * {string} method: get/post/put/etc, * {string} arrayName: name to post arraylike data. Only necessary when root data object is an array. * } * @example postToUrl('/UpdateUser', {Order {Id: 1, FirstName: 'Sally'}}); */ function postToUrl(path, data, options) { if (options === undefined) { options = {}; } var method = options.method || "post"; // Set method to post by default if not specified. var form = document.createElement("form"); form.setAttribute("method", method); form.setAttribute("action", path); function constructElements(item, parentString) { for (var key in item) { if (item.hasOwnProperty(key) && item[key] != null) { if (Object.prototype.toString.call(item[key]) === '[object Array]') { for (var i = 0; i < item[key].length; i++) { constructElements(item[key][i], parentString + key + "[" + i + "]."); } } else if (Object.prototype.toString.call(item[key]) === '[object Object]') { constructElements(item[key], parentString + key + "."); } else { var hiddenField = document.createElement("input"); hiddenField.setAttribute("type", "hidden"); hiddenField.setAttribute("name", parentString + key); hiddenField.setAttribute("value", item[key]); form.appendChild(hiddenField); } } } } //if the parent 'data' object is an array we need to treat it a little differently if (Object.prototype.toString.call(data) === '[object Array]') { if (options.arrayName === undefined) console.warn("Posting array-type to url will doubtfully work without an arrayName defined in options."); //loop through each array item at the parent level for (var i = 0; i < data.length; i++) { constructElements(data[i], (options.arrayName || "") + "[" + i + "]."); } } else { //otherwise treat it normally constructElements(data, ""); } document.body.appendChild(form); form.submit(); }; 

一个解决scheme是生成表单并提交。 一个实现是

 function post_to_url(url, params) { var form = document.createElement('form'); form.action = url; form.method = 'POST'; for (var i in params) { if (params.hasOwnProperty(i)) { var input = document.createElement('input'); input.type = 'hidden'; input.name = i; input.value = params[i]; form.appendChild(input); } } form.submit(); } 

所以我可以实现一个简单的URL缩短书签

 javascript:post_to_url('http://is.gd/create.php', {'URL': location.href}); 

这里有三个选项。

  1. 标准的JavaScript回答:使用框架! 大多数Ajax框架将抽象出一个简单的方法来创build一个XMLHTTPRequest POST。

  2. 自己创buildXMLHTTPRequest请求,将post传递给open方法而不是get。 ( 在XMLHTTPRequest(Ajax)使用POST方法的更多信息。)

  3. 通过JavaScript,dynamic创build一个表单,添加一个动作,添加您的input,并提交。

这是我用jQuery写的。 在Firefox和Internet Explorer中testing。

 function postToUrl(url, params, newWindow) { var form = $('<form>'); form.attr('action', url); form.attr('method', 'POST'); if(newWindow){ form.attr('target', '_blank'); } var addParam = function(paramName, paramValue){ var input = $('<input type="hidden">'); input.attr({ 'id': paramName, 'name': paramName, 'value': paramValue }); form.append(input); }; // Params is an Array. if(params instanceof Array){ for(var i=0; i<params.length; i++){ addParam(i, params[i]); } } // Params is an Associative array or Object. if(params instanceof Object){ for(var key in params){ addParam(key, params[key]); } } // Submit the form, then remove it from the page form.appendTo(document.body); form.submit(); form.remove(); } 

像其他人所build议的那样,我会沿着Ajax路线走下去:

 var xmlHttpReq = false; var self = this; // Mozilla/Safari if (window.XMLHttpRequest) { self.xmlHttpReq = new XMLHttpRequest(); } // IE else if (window.ActiveXObject) { self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP"); } self.xmlHttpReq.open("POST", "YourPageHere.asp", true); self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8'); self.xmlHttpReq.setRequestHeader("Content-length", QueryString.length); self.xmlHttpReq.send("?YourQueryString=Value"); 

最简单的方法是使用Ajax Post Request:

 $.ajax({ type: "POST", url: 'http://www.myrestserver.com/api', data: data, success: success, dataType: dataType }); 

哪里:

  • 数据是一个对象
  • dataType是服务器期望的数据(xml,json,script,text,html)
  • url是你的RESt服务器的地址或服务器端接受HTTP-POST的任何函数。

然后在成功处理程序redirect浏览器像window.location。

Prototype库包含一个带有“.toQueryString()”方法的Hashtable对象,该方法允许您轻松地将JavaScript对象/结构转换为查询string样式string。 由于post要求请求的“主体”是一个查询string格式化的string,这使得您的Ajax请求能够正常工作。 这是一个使用Prototype的例子:

 $req = new Ajax.Request("http://foo.com/bar.php",{ method: 'post', parameters: $H({ name: 'Diodeus', question: 'JavaScript posts a request like a form request', ... }).toQueryString(); }; 
 document.getElementById("form1").submit(); 

在我的情况下,它是完美的。

你可以在function上也使用它,

 function formSubmit() { document.getElementById("frmUserList").submit(); } 

使用这个你可以发布所有的input值。

FormObject是一个选项。 但是现在大多数浏览器都不支持FormObject。

这就像Alan的select2(上图)。 如何实例化httpobj是作为一个excercise。

 httpobj.open("POST", url, true); httpobj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); httpobj.onreadystatechange=handler; httpobj.send(post); 

这是基于使用jQuery的beauSD的代码。 它得到了改进,所以它对对象recursion地工作。

 function post(url, params, urlEncoded, newWindow) { var form = $('<form />').hide(); form.attr('action', url) .attr('method', 'POST') .attr('enctype', urlEncoded ? 'application/x-www-form-urlencoded' : 'multipart/form-data'); if(newWindow) form.attr('target', '_blank'); function addParam(name, value, parent) { var fullname = (parent.length > 0 ? (parent + '[' + name + ']') : name); if(value instanceof Object) { for(var i in value) { addParam(i, value[i], fullname); } } else $('<input type="hidden" />').attr({name: fullname, value: value}).appendTo(form); }; addParam('', params, ''); $('body').append(form); form.submit(); } 

您可以使用DHTMLdynamic添加表单,然后提交。

你可以使用像jQuery和$ .post方法的库。

又一个recursion的解决scheme,因为其他一些似乎被打破(我没有testing所有的)。 这一个取决于lodash 3.x和ES6(不需要jQuery):

 function createHiddenInput(name, value) { let input = document.createElement('input'); input.setAttribute('type','hidden'); input.setAttribute('name',name); input.setAttribute('value',value); return input; } function appendInput(form, name, value) { if(_.isArray(value)) { _.each(value, (v,i) => { appendInput(form, `${name}[${i}]`, v); }); } else if(_.isObject(value)) { _.forOwn(value, (v,p) => { appendInput(form, `${name}[${p}]`, v); }); } else { form.appendChild(createHiddenInput(name, value)); } } function postToUrl(url, data) { let form = document.createElement('form'); form.setAttribute('method', 'post'); form.setAttribute('action', url); _.forOwn(data, (value, name) => { appendInput(form, name, value); }); form.submit(); } 

我用来发布和自动引导用户到另一个页面的方法是只写一个隐藏的表单,然后自动提交。 请放心,隐藏的表单绝对不会在网页上留下空间。 代码会是这样的:

  <form name="form1" method="post" action="somepage.php"> <input name="fielda" type="text" id="fielda" type="hidden"> <textarea name="fieldb" id="fieldb" cols="" rows="" style="display:none"></textarea> </form> document.getElementById('fielda').value="some text for field a"; document.getElementById('fieldb').innerHTML="some text for multiline fieldb"; form1.submit(); 

应用自动提交

自动提交的应用程序将指导用户自动将另一页上的表单值返回到该页面。 这样的应用程序将是这样的:

 fieldapost=<?php echo $_post['fielda'];> if (fieldapost !="") { document.write("<form name='form1' method='post' action='previouspage.php'> <input name='fielda' type='text' id='fielda' type='hidden'> </form>"); document.getElementById('fielda').value=fieldapost; form1.submit(); } 

你可以做一个AJAX调用(可能使用库,如使用Prototype.js或JQuery)。 AJAX可以同时处理GET和POST选项。