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

