我正在尝试将浏览器指向另一个页面。如果我想要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不是答案。


当前回答

您可以使用jQuery的触发器方法提交表单,就像按下按钮一样,

$('form').trigger('submit')

它将在浏览器上提交。

其他回答

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

Try

函数post_to_url(url,obj){let id=`form_${+new Date()}`;文档.body.innerHTML+=`<form id=“${id}”action=“${url}”method=“POST”>${Object.keys(obj).map(k=>`<input-type=“hidden”name=“${k}”value=“${obj[k]}”>`)}</form>`this[id].submit();}//TEST-在第二个参数对象中可以有更多的键函数jump(){post_to_url('https://example.com/',{'q':'‘});}打开chrome>网络并按下按钮:<button onclick=“jump()”>发送POST</button>