JavaScript发布请求,例如表单提交

时间:2020-03-06 14:43:34  来源:igfitidea点击:

我正在尝试将浏览器定向到其他页面。如果我想要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();
}