XMLHttpRequestを使用してPOSTデータを送信する


526

JavaScriptでXMLHttpRequestを使用してデータを送信したいのですが。

HTMLで次のフォームがあるとします。

<form name="inputform" action="somewhere" method="post">
    <input type="hidden" value="person" name="user">
    <input type="hidden" value="password" name="pwd">
    <input type="hidden" value="place" name="organization">
    <input type="hidden" value="key" name="requiredkey">
</form>

JavaScriptでXMLHttpRequestを使用して同等のものをどのように書くことができますか?

回答:


748

以下のコードは、これを行う方法を示しています。

var http = new XMLHttpRequest();
var url = 'get_data.php';
var params = 'orem=ipsum&name=binny';
http.open('POST', url, true);

//Send the proper header information along with the request
http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

http.onreadystatechange = function() {//Call a function when the state changes.
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
}
http.send(params);

46
paramsjQueryのような文字列の代わりにオブジェクトを送信することは可能ですか?
Vadorequest 2014

4
いいえ、しかし、@ VadorequestのコメントはjQueryについて述べていました-彼は「jQueryのような」データを渡すことが可能かどうか尋ねました。私は、jQueryがそれをどのように行うと思い、したがって、これをどのように達成できるかについて述べました。
Dan Pantry、2015

11
@EdHeal、ConnectionおよびContent-Lengthヘッダーは設定できません。「安全でないヘッダー "content-length"の設定は拒否されました」と表示されます。stackoverflow.com/a/2624167/632951
Pacerier

76
注:open()の後の setRequestHeader()。私に1時間かかった、このコメントが誰かを1時間節約することを願おう;)
Kevin

4
application/jsonリクエストを送信することは可能ですか?

270
var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send('user=person&pwd=password&organization=place&requiredkey=key');

または、ブラウザのサポートを当てにできる場合は、FormDataを使用できます。

var data = new FormData();
data.append('user', 'person');
data.append('pwd', 'password');
data.append('organization', 'place');
data.append('requiredkey', 'key');

var xhr = new XMLHttpRequest();
xhr.open('POST', 'somewhere', true);
xhr.onload = function () {
    // do something to response
    console.log(this.responseText);
};
xhr.send(data);

4
FormDataはフォーム要素をコンストラクターの引数として取り、個別に値を追加する必要はありません
Juan Mendes

6
はい、しかし質問は提供されたフォームに相当するJavaScriptを記述し、JavaScriptを使用してフォームを送信しないことでした。
uKolka 2013年

3
投票数は少ないが正しいとマークされた回答は、2つの追加ヘッダーを使用します:http.setRequestHeader("Content-length", params.length);http.setRequestHeader("Connection", "close");。それらは必要ですか?それらはおそらく特定のブラウザでのみ必要ですか?(Content-Lengthヘッダーの設定は「まさに必要なもの」であったと言っている他のページへのコメントがあります)
Darren Cook

@Darren Cook実装に依存。私の経験から、主要なブラウザーは、提供するデータから自動的に「Content-length」(必須)を設定します。ほとんどの場合、「接続」ヘッダーはデフォルトで「キープアライブ」に設定されているため、しばらくの間接続を開いたままにしておくため、「閉じる」の場合のように後続のリクエストで接続を再確立する必要がありません。現在のページのURLを使用してコンソールでこれらのスニペットを試し、ブラウザのツールまたはWiresharkを使用してリクエストヘッダーを検査できます。
uKolka 2013年

4
@uKolkaそれはあなたの2番目の解決策ではリクエストContent-Typeが自動的に変更されるのではなく、返信に注意すべきmultipart/form-dataです。これはサーバー側とそこでの情報へのアクセス方法に深刻な影響を及ぼします。
AxeEffect 2017

84

最新のJavaScriptを使用してください!

を調べることをお勧めしfetchます。ES5と同等であり、Promiseを使用します。より読みやすく、簡単にカスタマイズできます。

const url = "http://example.com";
fetch(url, {
    method : "POST",
    body: new FormData(document.getElementById("inputform")),
    // -- or --
    // body : JSON.stringify({
        // user : document.getElementById('user').value,
        // ...
    // })
}).then(
    response => response.text() // .json(), etc.
    // same as function(response) {return response.text();}
).then(
    html => console.log(html)
);

Node.jsでは、次fetchを使用してインポートする必要があります。

const fetch = require("node-fetch");

同期的に使用したい場合(トップスコープでは機能しません):

const json = await fetch(url, optionalOptions)
  .then(response => response.json()) // .text(), etc.
  .catch((e) => {});

より詳しい情報:

Mozillaドキュメント

使用できます(2020年3月95%)

David Walshチュートリアル


4
多くのデバイスにはこれらの機能をサポートするブラウザーがないため、Webページの機能にとってこれが重要なことには、Promiseと太い矢印を使用しないでください。
ドミトリー

8
約束は90%カバーされます。function()あなたが好まない場合のために私は例を追加しました=>。開発者のエクスペリエンスを容易にするために、最新のJSを絶対に使用する必要があります。あなたが大企業でない限り、IEで立ち往生している少数の人々を心配することはそれだけの価値はありません
Gibolt

4
ファットアローもthisキーワードでは機能しません。それについて言及したいのですがthis、関数ファクトリーの代わりに、継承アーキテクチャーを使用する人々も密かに憎んでいます。私を許して、私はノードです。
agm1984

3
thisはペストも好きではないので、誰もが読むべきthisです。
Gibolt 2017年

2
互換性が心配な場合... Google es6 transpiler ... stackoverflow.com/questions/40205547/…。簡単に書いてください。互換性のある展開します。+1を避けthisます。
TamusJRoyce 2017

35

の最小限の使用によるFormDataAJAXリクエストの送信

<!DOCTYPE html>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=Edge, chrome=1"/>
<script>
"use strict";
function submitForm(oFormElement)
{
  var xhr = new XMLHttpRequest();
  xhr.onload = function(){ alert (xhr.responseText); } // success case
  xhr.onerror = function(){ alert (xhr.responseText); } // failure case
  xhr.open (oFormElement.method, oFormElement.action, true);
  xhr.send (new FormData (oFormElement));
  return false;
}
</script>
</head>

<body>
<form method="post" action="somewhere" onsubmit="return submitForm(this);">
  <input type="hidden" value="person"   name="user" />
  <input type="hidden" value="password" name="pwd" />
  <input type="hidden" value="place"    name="organization" />
  <input type="hidden" value="key"      name="requiredkey" />
  <input type="submit" value="post request"/>
</form>
</body>
</html>

備考

  1. これは、ユーザーが要求を送信するためにクリックする必要があるため、OPの質問には完全には答えません。しかし、これは、この種の単純な解決策を探している人々にとって役立つかもしれません。

  2. この例は非常に単純であり、 GETメソッドを。より洗練された例に興味がある場合は、優れたMDNドキュメントをご覧ください。XMLHttpRequest to Post HTML Formに関する同様の回答も参照してください。

  3. このソリューションの制限:Justin BlankThomas Munkが指摘したように(コメントを参照)、FormData IE9以下、およびAndroid 2.3のデフォルトのブラウザーではサポートされていません。


1
これに関する唯一のことは、FormDataがIE 9で利用できないと私が思うので、ポリフィルなしで多くの人がそれを使うことができないでしょう。developer.mozilla.org/en-US/docs/Web/API/FormData
Justin Blank

リンクをありがとう@ThomasMunk :-) FormDataIE9とAndroid 2.3を除く多くのブラウザでサポートされていることがわかります(OperaMiniですが、これは広く使用されていません)。乾杯;-)
olibre 2014年

2
エレガントなソリューションですが、指定しonsubmit="return submitForm(this);"ないとユーザーはリクエストのURLにリダイレクトされます。
Vic

@Vicの貢献に感謝します。回答を更新しました。乾杯;-)
olibre 2015

1
私はウェブ開発の経験はそれほどありません。あなたが戻っfalseたときにPOSTリクエストが確かに送信されていることがわかりました。場合はtrue返却され、元の(不要な)POSTリクエストが送信されます!正解です。ごめんなさい。
Markus L

30

ここに完全なソリューションがありapplication-jsonます:

// Input values will be grabbed by ID
<input id="loginEmail" type="text" name="email" placeholder="Email">
<input id="loginPassword" type="password" name="password" placeholder="Password">

// return stops normal action and runs login()
<button onclick="return login()">Submit</button>

<script>
    function login() {
        // Form fields, see IDs above
        const params = {
            email: document.querySelector('#loginEmail').value,
            password: document.querySelector('#loginPassword').value
        }

        const http = new XMLHttpRequest()
        http.open('POST', '/login')
        http.setRequestHeader('Content-type', 'application/json')
        http.send(JSON.stringify(params)) // Make sure to stringify
        http.onload = function() {
            // Do whatever with response
            alert(http.responseText)
        }
    }
</script>

バックエンドAPIがJSONを解析できることを確認してください。

たとえば、Express JSの場合:

import bodyParser from 'body-parser'
app.use(bodyParser.json())

1
すばらしいですが、XMLHttpRequest.openのasyncパラメータに「false」値を使用しないでください-これは非推奨であり、警告が表示されます
johnnycardy

そこにtrueを置くべきですか、それともそのパラメータを省略すべきですか?どちらが望ましいかを指定できる場合は、回答を更新します。
agm1984

1
デフォルトはtrueになっているはずですが、すべてのブラウザがそれを尊重しているかどうかはわかりません
johnnycardy

デフォルトのtrueを
前提

1
それは合理的であり、誰かが最初に始める詳細が1つ少ないので、私はそれが好きです。それを強調してくれてありがとう。
agm1984

25

プラグインは必要ありません!

以下のコードを選択し、それをブックマークバーにドラッグします(表示されない場合は、ブラウザーの設定から有効にします)。次に、そのリンクを編集します。

ここに画像の説明を入力してください

javascript:var my_params = prompt("Enter your parameters", "var1=aaaa&var2=bbbbb"); var Target_LINK = prompt("Enter destination", location.href); function post(path, params) { var xForm = document.createElement("form"); xForm.setAttribute("method", "post"); xForm.setAttribute("action", path); for (var key in params) { if (params.hasOwnProperty(key)) { var hiddenField = document.createElement("input"); hiddenField.setAttribute("name", key); hiddenField.setAttribute("value", params[key]); xForm.appendChild(hiddenField); } } var xhr = new XMLHttpRequest(); xhr.onload = function () { alert(xhr.responseText); }; xhr.open(xForm.method, xForm.action, true); xhr.send(new FormData(xForm)); return false; } parsed_params = {}; my_params.split("&").forEach(function (item) { var s = item.split("="), k = s[0], v = s[1]; parsed_params[k] = v; }); post(Target_LINK, parsed_params); void(0);

それで全部です!これで、任意のWebサイトにアクセスして、ブックマークバーのそのボタンをクリックできます。


注意:

上記のメソッドはメソッドを使用してデータを送信するXMLHttpRequestため、スクリプトをトリガーしている間は同じドメインにいる必要があります。これが、コードを任意のドメインに送信できるシミュレートされたFORM SUBMITTINGでデータを送信することを好む理由です。ここにそのコードを示します。

 javascript:var my_params=prompt("Enter your parameters","var1=aaaa&var2=bbbbb"); var Target_LINK=prompt("Enter destination", location.href); function post(path, params) {   var xForm= document.createElement("form");   xForm.setAttribute("method", "post");   xForm.setAttribute("action", path); xForm.setAttribute("target", "_blank");   for(var key in params) {   if(params.hasOwnProperty(key)) {        var hiddenField = document.createElement("input");      hiddenField.setAttribute("name", key);      hiddenField.setAttribute("value", params[key]);         xForm.appendChild(hiddenField);     }   }   document.body.appendChild(xForm);  xForm.submit(); }   parsed_params={}; my_params.split("&").forEach(function(item) {var s = item.split("="), k=s[0], v=s[1]; parsed_params[k] = v;}); post(Target_LINK, parsed_params); void(0); 

Mozillaの場合、これに類似したことを実行できますか?

できなかったしできなかった:| 125人の担当者はいません:| そして、私のプロフィールを見ると、私は136の賛成票を持っていることがわかります。反対票を投じる許可を得た後でも、必要でない限りそれを避けます:|

18
そして、あなたの質問は、OPが求めているものに実際には答えません。HTTPリクエストのBookMarking ...!?XmlHttpRequestあなたの答えに関連する点は見当たりません:|

2
驚くばかり。それが答えだったので、レビューの間に何らかの関係がほしかった。今ではそれは答えに加えて立ち寄るすべての人のためのgr8のヒントです。投票を取り消しました。歓声
アイスマン

5

同じ投稿を使用して同様の問題に直面し、このリンクで問題を解決しました。

 var http = new XMLHttpRequest();
 var url = "MY_URL.Com/login.aspx";
 var params = 'eid=' +userEmailId+'&amp;pwd='+userPwd

 http.open("POST", url, true);

 // Send the proper header information along with the request
 //http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
 //http.setRequestHeader("Content-Length", params.length);// all browser wont support Refused to set unsafe header "Content-Length"
 //http.setRequestHeader("Connection", "close");//Refused to set unsafe header "Connection"

 // Call a function when the state 
 http.onreadystatechange = function() {
    if(http.readyState == 4 && http.status == 200) {
        alert(http.responseText);
    }
 }
 http.send(params);

このリンクは情報を完成させました。


4
var util = {
    getAttribute: function (dom, attr) {
        if (dom.getAttribute !== undefined) {
            return dom.getAttribute(attr);
        } else if (dom[attr] !== undefined) {
            return dom[attr];
        } else {
            return null;
        }
    },
    addEvent: function (obj, evtName, func) {
        //Primero revisar attributos si existe o no.
        if (obj.addEventListener) {
            obj.addEventListener(evtName, func, false);

        } else if (obj.attachEvent) {
            obj.attachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = func;
            } else {
                obj[evtName] = func;
            }

        }

    },
    removeEvent: function (obj, evtName, func) {
        if (obj.removeEventListener) {
            obj.removeEventListener(evtName, func, false);
        } else if (obj.detachEvent) {
            obj.detachEvent(evtName, func);
        } else {
            if (this.getAttribute("on" + evtName) !== undefined) {
                obj["on" + evtName] = null;
            } else {
                obj[evtName] = null;
            }
        }

    },
    getAjaxObject: function () {
        var xhttp = null;
        //XDomainRequest
        if ("XMLHttpRequest" in window) {
            xhttp = new XMLHttpRequest();
        } else {
            // code for IE6, IE5
            xhttp = new ActiveXObject("Microsoft.XMLHTTP");
        }
        return xhttp;
    }

};

//START CODE HERE.

var xhr = util.getAjaxObject();

var isUpload = (xhr && ('upload' in xhr) && ('onprogress' in xhr.upload));

if (isUpload) {
    util.addEvent(xhr, "progress", xhrEvt.onProgress());
    util.addEvent(xhr, "loadstart", xhrEvt.onLoadStart);
    util.addEvent(xhr, "abort", xhrEvt.onAbort);
}

util.addEvent(xhr, "readystatechange", xhrEvt.ajaxOnReadyState);

var xhrEvt = {
    onProgress: function (e) {
        if (e.lengthComputable) {
            //Loaded bytes.
            var cLoaded = e.loaded;
        }
    },
    onLoadStart: function () {
    },
    onAbort: function () {
    },
    onReadyState: function () {
        var state = xhr.readyState;
        var httpStatus = xhr.status;

        if (state === 4 && httpStatus === 200) {
            //Completed success.
            var data = xhr.responseText;
        }

    }
};
//CONTINUE YOUR CODE HERE.
xhr.open('POST', 'mypage.php', true);
xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');


if ('FormData' in window) {
    var formData = new FormData();
    formData.append("user", "aaaaa");
    formData.append("pass", "bbbbb");

    xhr.send(formData);

} else {

    xhr.send("?user=aaaaa&pass=bbbbb");
}

1
こんにちはHugo、このコードは、ブラウザがサポートしている場合、進行状況のアップロードでデータまたはファイルを送信するためのものです。可能なすべてのイベントと互換性ブラウザーが含まれています。ブラウザから最新のオブジェクトクラスを使用してみます。それはあなたを助けますか?
toto

2

formdataの代わりにjsonオブジェクトを使用してみてください。以下は私のために働いているコードです。formdataも私にとっては機能しないため、このソリューションを思いつきました。

var jdata = new Object();
jdata.level = levelVal; // level is key and levelVal is value
var xhttp = new XMLHttpRequest();
xhttp.open("POST", "http://MyURL", true);
xhttp.setRequestHeader('Content-Type', 'application/json');
xhttp.send(JSON.stringify(jdata));

xhttp.onreadystatechange = function() {
    if (this.readyState == 4 && this.status == 200) {
      console.log(this.responseText);
    }
}

1

機能の読者がこの質問を見つけるためだけに。与えられたパスがある限り、受け入れられた回答は問題なく機能しますが、空白のままにすると、IEで失敗します。これが私が思いついたものです:

function post(path, data, callback) {
    "use strict";
    var request = new XMLHttpRequest();

    if (path === "") {
        path = "/";
    }
    request.open('POST', path, true);
    request.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
    request.onload = function (d) {
        callback(d.currentTarget.response);
    };
    request.send(serialize(data));
}

あなたはそうすることができます:

post("", {orem: ipsum, name: binny}, function (response) {
    console.log(respone);
})

1

これに触れるいくつかの重複があり、誰もそれについて本当に説明しません。私は説明するために受け入れられた答えの例を借ります

http.open('POST', url, true);
http.send('lorem=ipsum&name=binny');

説明のためhttp.onload(function() {})に、これを過度に単純化しました(その答えの古い方法の代わりに使用しています)。これをそのまま使用すると、サーバーがPOST本体を実際のkey=valueパラメーターではなく文字列として解釈していることがわかります(つまり、PHPは$_POST変数を表示しません)。あなたはしなければならないことを見るにはフォームのヘッダーを渡し、前にそれを行いますhttp.send()

http.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');

URLエンコードされたデータではapplication/jsonなくJSONを使用している場合は、代わりに渡します


1

これは私がxmlHttpRequestオブジェクトをフォームデータとしてのみ使用して投稿したかったので役に立ちました:

function sendData(data) {
  var XHR = new XMLHttpRequest();
  var FD  = new FormData();

  // Push our data into our FormData object
  for(name in data) {
    FD.append(name, data[name]);
  }

  // Set up our request
  XHR.open('POST', 'https://example.com/cors.php');

  // Send our FormData object; HTTP headers are set automatically
  XHR.send(FD);
}

https://developer.mozilla.org/en-US/docs/Learn/HTML/Forms/Sending_forms_through_JavaScript

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.