我正在尝试将浏览器指向另一个页面。如果我想要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'});
最好的跨浏览器实现是什么?
我需要一个改变浏览器位置的解决方案,就像提交表单一样。这不应该是异步的,也不应该使用XML,因此Ajax不是答案。
Prototype库包含一个Hashtable对象和一个“.toQueryString()”方法,它允许您轻松地将JavaScript对象/结构转换为查询字符串样式的字符串。由于post要求请求的“主体”是查询字符串格式的字符串,这允许Ajax请求作为post正常工作。以下是使用原型的示例:
$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();
};
接受的答案将像提交本地表单一样重新加载页面。此修改版本将通过XHR提交:
function post(path, params) {
const form = document.createElement('form');
for (const key in params) {
if (params.hasOwnProperty(key)) {
const hiddenField = document.createElement('input');
hiddenField.type = 'hidden';
hiddenField.name = key;
hiddenField.value = params[key];
form.appendChild(hiddenField);
}
}
var button = form.ownerDocument.createElement('input');
button.type = 'submit';
form.appendChild(button);
form.onsubmit = async function (e) {
console.log('hi');
e.preventDefault();
const form = e.currentTarget;
try {
const formData = new FormData(form);
const response = await fetch(path, {
method: 'POST',
body: formData,
});
console.log(response);
} catch (error) {
console.error(error);
}
};
document.body.appendChild(form);
button.click();
}
Rakesh Pai的回答令人惊讶,但当我试图发布一个名为submit的表单时,我(在Safari中)遇到了一个问题。例如,post_to_url(“http://google.com/“,{submit:”submit“});。我已经稍微修补了该函数,以避免这种变量空间冲突。
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!
还有另一个递归解决方案,因为其他一些似乎已被破坏(我没有测试所有这些)。这取决于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();
}