JavaScript发布请求,例如表单提交
我正在尝试将浏览器定向到其他页面。如果我想要GET请求,我可能会说
document.location.href = 'http://example.com/q=a';
但是,除非使用POST请求,否则我尝试访问的资源将无法正确响应。如果不是动态生成的,我可能会使用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'});
最好的跨浏览器实现是什么?
编辑
对不起,我不清楚。我需要一个更改浏览器位置的解决方案,就像提交表单一样。如果XMLHttpRequest可以做到这一点,那不是很明显。而且这不应该是异步的,也不应该使用XML,因此Ajax并不是答案。
解决方案
我们可以使用DHTML动态添加表单,然后提交。
我们可以进行AJAX调用(可能使用诸如Prototype.js或者JQuery之类的库)。 AJAX可以处理GET和POST选项。
我们可以使用jQuery之类的库及其$ .post方法。
这里有三个选择。
- 标准JavaScript答案:使用框架!大多数Ajax框架都会使我们抽象出进行XMLHTTPRequest POST的简便方法。
- 自己发出XMLHTTPRequest请求,将post传递到open方法中,而不是将其传递给get方法。 (有关在XMLHTTPRequest(Ajax)中使用POST方法的更多信息。)
- 通过JavaScript动态创建表单,添加操作,添加输入并提交。
Prototype库包含一个带有" .toQueryString()"方法的Hashtable对象,它使我们可以轻松地将JavaScript对象/结构转换为查询字符串样式字符串。由于该帖子要求请求的"正文"为查询字符串格式的字符串,因此这使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(); };
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'});
编辑:由于这已经被大肆抨击,我猜人们会大量复制粘贴。因此,我添加了" hasOwnProperty"检查来修复所有无意的错误。
使用此答案中提供的createElement
函数,这是必需的,因为IE损坏了通常使用document.createElement
创建的元素上的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); }
@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();
当然,我们应该使用Prototype或者jQuery之类的JavaScript框架...
我会像其他人建议的那样沿着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");
这就像艾伦的选项2(上方)。如何实例化httpobj仍然是一项练习。
httpobj.open("POST", url, true); httpobj.setRequestHeader('Content-Type','application/x-www-form-urlencoded; charset=UTF-8'); httpobj.onreadystatechange=handler; httpobj.send(post);
一种解决方案是生成表格并提交。一种实现是
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});
如果已安装原型,则可以收紧代码以生成并提交隐藏的表单,如下所示:
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();
Rakesh Pai的答案令人惊讶,但当我尝试发布带有名为" submit"的字段的表单时(对于Safari),这对我来说是一个问题。例如," post_to_url(" http://google.com/",{提交:"提交"});`。我已经对该函数进行了一些修补,以解决此可变空间冲突。
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!
这是我使用jQuery编写的方式。在Firefox和InternetExplorer中进行了测试。
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(); }