JavaScript を介してクロスドメイン POST リクエストを送信するにはどうすればよいですか?
注 - ページを更新するべきではなく、後で応答を取得して解析する必要があります。
JavaScript を介してクロスドメイン POST リクエストを送信するにはどうすればよいですか?
注 - ページを更新するべきではなく、後で応答を取得して解析する必要があります。
更新:続行する前に、全員がCORS に関するhtml5rocks チュートリアルを読んで理解する必要があります。わかりやすくてとてもわかりやすいです。
POST されているサーバーを制御する場合は、サーバーに応答ヘッダーを設定して、「クロスオリジン リソース共有標準」を利用するだけです。この回答は、このスレッドの他の回答で議論されていますが、私の意見ではあまり明確ではありません。
要するに、from.com/1.html から to.com/postHere.php へのクロスドメイン POST を実行する方法を次に示します (例として PHP を使用)。Access-Control-Allow-Origin
注: NONリクエストに対してのみ設定する必要があります。OPTIONS
この例では、常に小さなコード スニペットのすべてのヘッダーを設定します。
postHere.php で次のように設定します。
switch ($_SERVER['HTTP_ORIGIN']) {
case 'http://from.com': case 'https://from.com':
header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
header('Access-Control-Max-Age: 1000');
header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
break;
}
これにより、スクリプトでクロスドメイン POST、GET、および OPTIONS を作成できます。これは読み進めていくうちに明らかになる...
JS からクロスドメイン POST をセットアップします (jQuery の例):
$.ajax({
type: 'POST',
url: 'https://to.com/postHere.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
alert('POST failed.');
}
});
ステップ 2 で POST を実行すると、ブラウザは「OPTIONS」メソッドをサーバーに送信します。これは、ブラウザによる「スニフ」であり、サーバーへの POST でサーバーがクールかどうかを確認します。サーバーは、リクエストが「 http://from.com」または「https://from.com 」から発信された場合、ブラウザに POST|GET|ORIGIN のOKを伝える「Access-Control-Allow-Origin」で応答します。サーバーは問題ないので、ブラウザーは 2 番目の要求 (今回は POST) を行います。送信するコンテンツ タイプをクライアントに設定させることをお勧めします。そのため、それも許可する必要があります。
MDN にはHTTP アクセス制御に関する優れた記事があり、フロー全体がどのように機能するかを詳しく説明しています。彼らのドキュメントによると、「クロスサイト XMLHttpRequest をサポートするブラウザーで動作する」はずです。ただし、これは少し誤解を招く可能性があります。クロス ドメイン POST を許可するのは最近のブラウザーだけだと思うからです。これが safari、chrome、FF 3.6 でのみ動作することを確認しました。
これを行う場合は、次の点に注意してください。
リモートサーバーを制御する場合は、この回答で説明されているように、おそらく CORS を使用する必要があります。IE8 以降、および最近のすべてのバージョンの FF、GC、および Safari でサポートされています。(ただし、IE8 および 9 では、CORS はリクエストで Cookie を送信することを許可しません。)
したがって、リモート サーバーを制御しない場合、または IE7 をサポートする必要がある場合、または Cookie が必要で IE8/9 をサポートする必要がある場合は、おそらく iframe 手法を使用することをお勧めします。
サンプルコードは次のとおりです。IE6、IE7、IE8、IE9、FF4、GC11、S5 でテストしました。
function crossDomainPost() {
// Add the iframe with a unique name
var iframe = document.createElement("iframe");
var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
document.body.appendChild(iframe);
iframe.style.display = "none";
iframe.contentWindow.name = uniqueString;
// construct a form with hidden inputs, targeting the iframe
var form = document.createElement("form");
form.target = uniqueString;
form.action = "http://INSERT_YOUR_URL_HERE";
form.method = "POST";
// repeat for each parameter
var input = document.createElement("input");
input.type = "hidden";
input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
form.appendChild(input);
document.body.appendChild(form);
form.submit();
}
注意してください!iframe は別のドメインに存在するため、POST の応答を直接読み取ることはできません。フレームが異なるドメインから相互に通信することは許可されていません。これが同一生成元ポリシーです。
window.postMessage
リモート サーバーを制御しているが、CORS を使用できない場合 (たとえば、IE8/IE9 を使用していて、Cookie を使用する必要があるため)、および/またはを使用するなど、同一生成元ポリシーを回避する方法があります。古いブラウザーでクロスドメイン クロスフレーム メッセージを送信できるようにする多くのライブラリの 1 つ:
リモートサーバーを制御しないと、POST の応答を読み取ることができません。そうしないと、セキュリティ上の問題が発生します。
疑似コード
var ifr = document.createElement('iframe');
var frm = document.createElement('form');
frm.setAttribute("action", "yoururl");
frm.setAttribute("method", "post");
// create hidden inputs, add them
// not shown, but similar (create, setAttribute, appendChild)
ifr.appendChild(frm);
document.body.appendChild(ifr);
frm.submit();
おそらく、iframe を非表示にして絶対に配置するようにスタイルを設定する必要があります。ブラウザでクロスサイト投稿が許可されるかどうかはわかりませんが、許可されている場合は、これがその方法です。
複雑にしないでおく:
クロスドメイン POST:
使用crossDomain: true,
ページを更新しないでください:
いいえ、サーバーが応答を返すときにsuccess
またはerror
$.ajax({
type: "POST",
url: "http://www.yoururl.com/",
crossDomain: true,
data: 'param1=value1¶m2=value2',
success: function (data) {
// do something with server response data
},
error: function (err) {
// handle your error logic here
}
});
関係するすべてのサーバーにアクセスできる場合は、他のドメインで要求されているページの返信のヘッダーに次のように入力します。
PHP:
header('Access-Control-Allow-Origin: *');
たとえば、Drupal の xmlrpc.php コードでは、次のようにします。
function xmlrpc_server_output($xml) {
$xml = '<?xml version="1.0"?>'."\n". $xml;
header('Connection: close');
header('Content-Length: '. strlen($xml));
header('Access-Control-Allow-Origin: *');
header('Content-Type: application/x-www-form-urlencoded');
header('Date: '. date('r'));
// $xml = str_replace("\n", " ", $xml);
echo $xml;
exit;
}
これはおそらくセキュリティ上の問題を引き起こすため、適切な手段を講じてリクエストを確認する必要があります。
http://taiyolab.com/mbtweet/scripts/twitterapi_call.jspost_method
で関数を確認してください- 上記の iframe メソッドの良い例です。
2つの非表示のiframeを作成します(cssスタイルに「display:none;」を追加します)。2番目のiframeが自分のドメイン上の何かを指すようにします。
非表示のフォームを作成し、そのメソッドをtarget =最初のiframeで「post」に設定し、オプションでenctypeを「multipart / form-data」に設定します(写真のようなマルチパートデータを送信したいので、POSTを実行したいと思います?)
準備ができたら、フォームsubmit()をPOSTにします。
他のドメインにIframeとのクロスドメイン通信を行うJavaScriptを返すことができれば(http://softwareas.com/cross-domain-communication-with-iframes)、運が良ければ、応答をキャプチャできます。同じように。
もちろん、サーバーをプロキシとして使用する場合は、これをすべて回避できます。フォームを自分のサーバーに送信するだけで、他のサーバーにリクエストがプロキシされ(他のサーバーがIPの不一致に気付くように設定されていない場合)、応答を取得して、好きなものを返します。
注意すべきもう1つの重要なこと!!! 上記の例では、使用方法が説明されています
$.ajax({
type : 'POST',
dataType : 'json',
url : 'another-remote-server',
...
});
JQuery 1.6以下には、クロスドメインXHRのバグがあります。Firebugによると、OPTIONS以外のリクエストは送信されませんでした。POSTなし。まったく。
コードのテスト/調整に5時間費やしました。リモートサーバー(スクリプト)に多くのヘッダーを追加します。効果なし。しかし後で、JQuery libを1.6.4に更新し、すべてが魅力のように機能します。
JQuery AJAX を使用する ASP.net MVC 環境でこれを行う場合は、次の手順に従います (これは、このスレッドで提供されているソリューションの概要です) 。
"caller.com" (任意の Web サイト) が "server.com" (ASP.net MVC アプリケーション) に投稿する必要があるとします。
「server.com」アプリの Web.config で、次のセクションを追加します。
<httpProtocol>
<customHeaders>
<add name="Access-Control-Allow-Origin" value="*" />
<add name="Access-Control-Allow-Headers" value="Content-Type" />
<add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
</customHeaders>
</httpProtocol>
「server.com」では、投稿先のコントローラー (「ホーム」と呼ばれる) で次のアクションを行います。
[HttpPost]
public JsonResult Save()
{
//Handle the post data...
return Json(
new
{
IsSuccess = true
});
}
次に、「caller.com」から、次のようにフォーム (html ID「formId」を持つ) から「server.com」にデータを投稿します。
$.ajax({
type: "POST",
url: "http://www.server.com/home/save",
dataType: 'json',
crossDomain: true,
data: $(formId).serialize(),
success: function (jsonResult) {
//do what ever with the reply
},
error: function (jqXHR, textStatus) {
//handle error
}
});
もう1つの方法があります(html5機能を使用)。他のドメインでホストされているプロキシ iframe を使用できます。postMessage を使用してその iframe にメッセージを送信すると、その iframe は POST 要求を (同じドメインで) 実行し、postMessage を応答とともに親ウィンドウに戻すことができます。
sender.com の親
var win = $('iframe')[0].contentWindow
function get(event) {
if (event.origin === "http://reciver.com") {
// event.data is response from POST
}
}
if (window.addEventListener){
addEventListener("message", get, false)
} else {
attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");
reciver.comのiframe
function listener(event) {
if (event.origin === "http://sender.com") {
var data = JSON.parse(event.data);
$.post(data.url, data.data, function(reponse) {
window.parent.postMessage(reponse, "*");
});
}
}
// don't know if we can use jQuery here
if (window.addEventListener){
addEventListener("message", listener, false)
} else {
attachEvent("onmessage", listener)
}
最良の方法は、クロスオリジンリソースシェアリングポリフィルhttps://github.com/Modernizr/Modernizr/wiki/HTML5-の1つでXMLHttpRequest(jQueryの$ .ajax()、$。post()など)を使用することだと思います。 Cross-Browser-Polyfills#wiki-CORS
高レベル.... other-serve.your-server.com が other-server.com を指すように、サーバーに cname をセットアップする必要があります。
あなたのページは、other-server.com へのトランスポートとして機能する非表示の iframe を動的に作成します。次に、JS を介してページから other-server.com に通信し、データをページに返すコールバックを行う必要があります。
可能ですが、your-server.com および other-server.com からの調整が必要です
これは古い質問ですが、いくつかの新しいテクノロジーが誰かを助けるかもしれません。
他のサーバーへの管理アクセス権がある場合は、オープンソースのForgeプロジェクトを使用してクロスドメインPOSTを実行できます。Forgeは、FlashのrawソケットAPIを利用するクロスドメインJavaScriptXmlHttpRequestラッパーを提供します。POSTはTLSを介して実行することもできます。
POST先のサーバーへの管理アクセスが必要な理由は、ドメインからのアクセスを許可するクロスドメインポリシーを提供する必要があるためです。
YQL カスタム テーブル + JS XHR で可能になるはずです。http://developer.yahoo.com/yql/guide/index.html をご覧 ください
クライアント側(js)のhtmlスクレイピングに使用していますが、正常に動作します(完全なオーディオプレーヤーがあり、インターネット/プレイリスト/歌詞/最後のfm情報、すべてのクライアントjs + YQLを検索できます)