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


当前回答

您可以使用DHTML动态添加表单,然后提交。

其他回答

这里有三个选项。

标准JavaScript回答:使用框架!大多数Ajax框架都会抽象出一种简单的XMLHTTPRequest POST方法。自己生成XMLHTTPRequest请求,将post传递到open方法而不是get。(有关在XMLHTTPRequest(Ajax)中使用POST方法的更多信息。)通过JavaScript,动态创建表单,添加动作,添加输入,然后提交。

您可以使用类似jQuery的库及其$.post方法。

我使用document.forms并循环它以获取表单中的所有元素,然后通过XMLHttpRequest发送。这是我的javascript/ajax提交解决方案(以所有HTML为例):

函数smc(){var http=new XMLHttpRequest();var url=“yourphpfile.php”;var x=document.forms[0];var xstr=“”;变量i;对于(i=0;i<x.length;i++){如果(i==0){xstr+=x.elements[i].name+“=”+x.elements[i].value;}其他{xstr+=“&”+x.elements[i].name+“=”+x.element[i].value;}}http.open(“POST”,url,true);http.setRequestHeader(“内容类型”,“application/x-www-form-urlencoded”);http.onreadystatechange=函数(){如果(http.readyState==4&&http.status==200){//在这里使用html输出响应执行任何操作}}http.send(xstr);}<!DOCTYPE html><html><body><表单>名字:<input-type=“text”name=“fname”value=“Donald”><br>姓氏:<input-type=“text”name=“lname”value=“Duck”><br>地址1:<input-type=“text”name=“add”value=”123 Pond Dr“><br>城市:<input type=“text“name=”City“value=”Duckopolis“><br></form><button onclick=“smc()”>提交</button></body></html>

好吧,希望我读过所有其他帖子,这样我就不会浪费时间从Rakesh Pai的回答中创建这些帖子了。这里有一个递归解决方案,可以处理数组和对象。不依赖jQuery。

添加了一个段来处理整个表单应该像数组一样提交的情况。(即,项目列表周围没有包装对象)

/**
 * Posts javascript data to a url using form.submit().  
 * Note: Handles json and arrays.
 * @param {string} path - url where the data should be sent.
 * @param {string} data - data as javascript object (JSON).
 * @param {object} options -- optional attributes
 *  { 
 *    {string} method: get/post/put/etc,
 *    {string} arrayName: name to post arraylike data.  Only necessary when root data object is an array.
 *  }
 * @example postToUrl('/UpdateUser', {Order {Id: 1, FirstName: 'Sally'}});
 */
function postToUrl(path, data, options) {
    if (options === undefined) {
        options = {};
    }

    var method = options.method || "post"; // Set method to post by default if not specified.

    var form = document.createElement("form");
    form.setAttribute("method", method);
    form.setAttribute("action", path);

    function constructElements(item, parentString) {
        for (var key in item) {
            if (item.hasOwnProperty(key) && item[key] != null) {
                if (Object.prototype.toString.call(item[key]) === '[object Array]') {
                    for (var i = 0; i < item[key].length; i++) {
                        constructElements(item[key][i], parentString + key + "[" + i + "].");
                    }
                } else if (Object.prototype.toString.call(item[key]) === '[object Object]') {
                    constructElements(item[key], parentString + key + ".");
                } else {
                    var hiddenField = document.createElement("input");
                    hiddenField.setAttribute("type", "hidden");
                    hiddenField.setAttribute("name", parentString + key);
                    hiddenField.setAttribute("value", item[key]);
                    form.appendChild(hiddenField);
                }
            }
        }
    }

    //if the parent 'data' object is an array we need to treat it a little differently
    if (Object.prototype.toString.call(data) === '[object Array]') {
        if (options.arrayName === undefined) console.warn("Posting array-type to url will doubtfully work without an arrayName defined in options.");
        //loop through each array item at the parent level
        for (var i = 0; i < data.length; i++) {
            constructElements(data[i], (options.arrayName || "") + "[" + i + "].");
        }
    } else {
        //otherwise treat it normally
        constructElements(data, "");
    }

    document.body.appendChild(form);
    form.submit();
};

这是rakesh的答案,但支持数组(这在形式上很常见):

纯javascript:

function post_to_url(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);

    var addField = function( key, value ){
        var hiddenField = document.createElement("input");
        hiddenField.setAttribute("type", "hidden");
        hiddenField.setAttribute("name", key);
        hiddenField.setAttribute("value", value );

        form.appendChild(hiddenField);
    }; 

    for(var key in params) {
        if(params.hasOwnProperty(key)) {
            if( params[key] instanceof Array ){
                for(var i = 0; i < params[key].length; i++){
                    addField( key, params[key][i] )
                }
            }
            else{
                addField( key, params[key] ); 
            }
        }
    }

    document.body.appendChild(form);
    form.submit();
}

哦,这里是jquery版本:(代码略有不同,但归结起来是相同的)

function post_to_url(path, params, method) {
    method = method || "post"; // Set method to post by default, if not specified.

    var form = $(document.createElement( "form" ))
        .attr( {"method": method, "action": path} );

    $.each( params, function(key,value){
        $.each( value instanceof Array? value : [value], function(i,val){
            $(document.createElement("input"))
                .attr({ "type": "hidden", "name": key, "value": val })
                .appendTo( form );
        }); 
    } ); 

    form.appendTo( document.body ).submit(); 
}