javascript - 送信 - js get form submit




フォーム送信のようなJavaScript投稿リクエスト (19)

1つの解決策は、フォームを生成して提出することです。 1つの実装は

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

ブラウザを別のページに誘導しようとしています。 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は答えではありません。


3つのオプションがあります。

  1. 標準のJavaScript答え:フレームワークを使用してください! ほとんどのAjaxフレームワークは、 XMLHttpRequest POSTを簡単に作成する方法を抽象化します。

  2. 取得の代わりに公開メソッドにPOSTを渡して、XMLHTTPRequestリクエストを自分で作成します。 ( XMLHTTPRequest(Ajax)のPOSTメソッドの使用の詳細を参照しください

  3. JavaScriptを使用して、フォームを動的に作成し、アクションを追加し、入力を追加し、それを送信します。


AJAX呼び出しを行うことができます(Prototype.jsやJQueryなどのライブラリを使用している可能性があります)。 AJAXはGETオプションとPOSTオプションの両方を扱うことができます。


DHTMLを使用してフォームを動的に追加してから送信することができます。


この答えで提供されているcreateElement関数を使用します 。これは、 document.createElement通常作成される要素のname属性によるIEの壊れやすさのために必要です

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

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!

Prototypeインストールされている場合は、次のように隠しフォームを生成して送信するためにコードを強化することができます。

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

FormDataはオプションです。 しかしFormObjectは現在ほとんどのブラウザでサポートされていません。


いいえ、フォーム送信のようなJavaScriptポストリクエストはありません。

あなたが持つことができるのはHTML形式のもので、それをJavaScriptで送信します。 (このページで何度も説明したように)

あなた自身でHTMLを作成することができます.HTMLを記述するためにJavaScriptは必要ありません。 人々がそれを示唆すれば、それはばかげているだろう。

<form id="ninja" action="http://example.com/" method="POST">
  <input id="donaldduck" type="hidden" name="q" value="a">
</form>

あなたの関数は、あなたが望むようにフォームを構成するだけです。

function postToURL(a,b,c){
   document.getElementById("ninja").action     = a;
   document.getElementById("donaldduck").name  = b;
   document.getElementById("donaldduck").value = c;
   document.getElementById("ninja").submit();
}

次に、それを好きなように使います。

postToURL("http://example.com/","q","a");

しかし、私は単に機能を残して、ちょうどやります。

   document.getElementById('donaldduck').value = "a";
   document.getElementById("ninja").submit();

最後に、スタイルの決定はccsファイルに格納されます。

.ninja{ 
  display:none;
}

個人的に私はフォームは名前で扱われるべきだと思うが、それは今は重要ではない。


ここでは、jQueryを使ってどのように記述したかを示します。 FirefoxとInternet Explorerでテストされています。

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

これはAlanのオプション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);

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

これは、jQueryを使ったbeauSDのコードに基づいています。 オブジェクト上で再帰的に動作するように改良されています。

function post(url, params, urlEncoded, newWindow) {
    var form = $('<form />').hide();
    form.attr('action', url)
        .attr('method', 'POST')
        .attr('enctype', urlEncoded ? 'application/x-www-form-urlencoded' : 'multipart/form-data');
    if(newWindow) form.attr('target', '_blank');

    function addParam(name, value, parent) {
        var fullname = (parent.length > 0 ? (parent + '[' + name + ']') : name);
        if(value instanceof Object) {
            for(var i in value) {
                addParam(i, value[i], fullname);
            }
        }
        else $('<input type="hidden" />').attr({name: fullname, value: value}).appendTo(form);
    };

    addParam('', params, '');

    $('body').append(form);
    form.submit();
}

さて、私は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();
};

ユーザーを自動的に投稿して別のページに誘導する方法は、隠しフォームを作成してから自動送信する方法です。 隠されたフォームはWebページに絶対にスペースを必要としません。 コードは次のようになります。

    <form name="form1" method="post" action="somepage.php">
    <input name="fielda" type="text" id="fielda" type="hidden">

    <textarea name="fieldb" id="fieldb" cols="" rows="" style="display:none"></textarea>
</form>
    document.getElementById('fielda').value="some text for field a";
    document.getElementById('fieldb').innerHTML="some text for multiline fieldb";
    form1.submit();

自動提出の申請

自動提出のアプリケーションは、ユーザーが自動的に他のページにそのページに戻すフォーム値を指示することです。 そのようなアプリケーションは次のようになります。

fieldapost=<?php echo $_post['fielda'];>
if (fieldapost !="") {
document.write("<form name='form1' method='post' action='previouspage.php'>
  <input name='fielda' type='text' id='fielda' type='hidden'>
</form>");
document.getElementById('fielda').value=fieldapost;
form1.submit();
}

他の人たちがAjaxのようなものを提案したので、私は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");

私のソリューションは、@ RakeshPaiの現在受け入れられている解決策とは異なり、深く入れ子になったオブジェクトをエンコードします。

'qs' npmライブラリとstringify関数を使用して、ネストされたオブジェクトをパラメータに変換します。

このコードは、Railsのバックエンドでうまく動作しますが、stringifyに渡されるオプションを変更することで、必要なバックエンドで動作するように変更することができます。 Railsでは、arrayFormatを "かっこ"に設定する必要があります。

import qs from "qs"

function normalPost(url, params) {
  var form = document.createElement("form");
  form.setAttribute("method", "POST");
  form.setAttribute("action", url);

  const keyValues = qs
    .stringify(params, { arrayFormat: "brackets", encode: false })
    .split("&")
    .map(field => field.split("="));

  keyValues.forEach(field => {
    var key = field[0];
    var value = field[1];
    var hiddenField = document.createElement("input");
    hiddenField.setAttribute("type", "hidden");
    hiddenField.setAttribute("name", key);
    hiddenField.setAttribute("value", value);
    form.appendChild(hiddenField);
  });
  document.body.appendChild(form);
  form.submit();
}

例:

normalPost("/people/new", {
      people: [
        {
          name: "Chris",
          address: "My address",
          dogs: ["Jordan", "Elephant Man", "Chicken Face"],
          information: { age: 10, height: "3 meters" }
        },
        {
          name: "Andrew",
          address: "Underworld",
          dogs: ["Doug", "Elf", "Orange"]
        },
        {
          name: "Julian",
          address: "In a hole",
          dogs: ["Please", "Help"]
        }
      ]
    });

これらのRailsパラメータを生成します。

{"authenticity_token"=>"...",
 "people"=>
  [{"name"=>"Chris", "address"=>"My address", "dogs"=>["Jordan", "Elephant Man", "Chicken Face"], "information"=>{"age"=>"10", "height"=>"3 meters"}},
   {"name"=>"Andrew", "address"=>"Underworld", "dogs"=>["Doug", "Elf", "Orange"]},
   {"name"=>"Julian", "address"=>"In a hole", "dogs"=>["Please", "Help"]}]}

私の場合、これは完全に機能します:

document.getElementById("form1").submit();

あなたは次のような関数で使うことができます:

function formSubmit() {
     document.getElementById("frmUserList").submit();
} 

これを使用すると、すべての入力値を転記することができます。


 /**
 * sends a request to the specified url from a form. this will change the window location.
 * @param {string} path the path to send the post request to
 * @param {object} params the paramiters to add to the url
 * @param {string} [method=post] the method to use on the form
 */

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

編集 :これはあまりにもupvotedして以来、私は人々がコピー貼りたくなると思います。 だから、不注意なバグを修正するためにhasOwnPropertyチェックを追加しました。





html-form