web-dev-qa-db-ja.com

クロスサイトAJAXリクエスト

Webサイトから別のドメインでホストされているAJAX WebサービスにRESTリクエストを送信する必要があります。

これはInternetExplorerでは問題なく機能しますが、MozillaやGoogleなどの他のブラウザChromeは、クロスサイトAJAXリクエストを禁止する、はるかに厳しいセキュリティ制限を課しています。

問題は、サイトがホストされているドメインやWebサーバーを制御できないことです。これは、私のREST Webサービスを別の場所で実行する必要があり、リダイレクトメカニズムを導入できないことを意味します。

非同期呼び出しを行うJavaScriptコードは次のとおりです。

var serviceUrl = "http://myservicedomain";
var payload = "<myRequest><content>Some content</content></myRequest>";
var request = new XMLHttpRequest();
request.open("POST", serviceUrl, true); // <-- This fails in Mozilla Firefox amongst other browsers
request.setRequestHeader("Content-type", "text/xml");
request.send(payload);

Internet Explorer以外のブラウザでこれを機能させるにはどうすればよいですか?

23

多分 [〜#〜] jsonp [〜#〜] が役立つでしょう。

注意:xmlの代わりにjsonを使用するようにメッセージを変更する必要があります

編集

Flickrや Twitter などの主要なサイトはコールバックなどでjsonpをサポートしています

14
redsquare

回答としてマークされた投稿は誤りです。iframeドキュメントは親にアクセスできません。同一生成元ポリシーは両方の方法で機能します。

事実は、xmlhttprequestを使用してRESTベースのWebサービスを利用することは決して不可能です。別のドメインから(フレームワークなしで)データをロードする唯一の方法は、JSONPを使用することです。他のソリューションでは、独自のドメインに配置されたサーバー側プロキシ、またはリモートドメインに配置されたクライアント側プロキシと、ドキュメント間で通信するためのある種のクロスサイト通信( easyXDM など)が必要です。

5
Sean Kinsey

あまり明確ではない回避策(ただし機能します)は、別のサイトへのリクエストのコンテナーとしてiframeを使用することです。問題は、親がiframeのコンテンツにアクセスできず、iframeの「src」属性しかナビゲートできないことです。ただし、iframeコンテンツは親のコンテンツにアクセスできます。

したがって、iframeのコンテンツがわかっている場合は、親ページのJavaScriptコンテンツを呼び出すか、親のDOMに直接アクセスできます。

編集:サンプル:

function ajaxWorkaroung() {
    var frm = gewtElementById("myIFrame")
    frm.src = "http://some_other_domain"
}
function ajaxCallback(parameter){
    // this function will be called from myIFrame's content
}
3
TcKs

これがIEで機能するという事実は、IEのセキュリティの問題であり、機能ではありません。

残念ながら、クロスサイトスクリプティングは禁止されており、受け入れられている回避策は、独自のドメインを介してリクエストをプロキシすることです。サーバーサイドコードを追加または変更する機能は本当にありませんか?

さらに、スクリプトタグを介したデータの取得を含む2番目の回避策は、GETリクエストのみをサポートします。これは、SOAPサービスでハッキングできる可能性がありますが、 POSTあなたが説明するRESTfulサービスへのリクエスト。

AJAXソリューションが存在するかどうかは本当にわかりません。<form>ソリューションに戻る可能性があります。

3
annakata

サービスドメインがクロスオリジンリソースシェアリング(CORS)を受け入れるようにします。

典型的なシナリオ:ほとんどのCORS準拠のブラウザーは、最初にOPTIONSヘッダーを送信します。サーバーは、このヘッダーに、受け入れられるヘッダーに関する情報を返す必要があります。ヘッダーが提供されたリクエストに対するサービスの要件(許可されたメソッドがGETとPOST、Allowed-Origin *など)を満たしている場合、ブラウザーは適切なメソッド(GET、POSTなど)を使用してリクエストを再送信します。

これ以降のすべては、IEを使用している場合と同じです。より簡単に言えば、同じドメインに投稿している場合です。

注意事項:一部のサービス開発SDK(特にWCF)は要求の処理を試みます。その場合、要求に応答するためにOPTIONSメソッドを前処理し、サーバー上でメソッドが2回呼び出されないようにする必要があります。

つまり、問題はサーバー側にあります。

編集 CORSのIE 9以下では、完全に実装されていないという問題が1つあります。幸い、サーバーから呼び出しを行うことでこの問題を解決できます。 -サービスのサイドコードをサーバー経由で返します(例:mypage.aspx?service = blah&method = blahblah&p0 = firstParam = something)。ここから、サーバーサイドコードはリクエスト/レスポンスストリームモデルを実装する必要があります。

2
jkrieg

Originドメインでサーバー側プロキシを使用するだけです。次に例を示します。 http://jquery-howto.blogspot.com/2009/04/cross-domain-ajax-querying-with-jquery.html

1
Laurent

もう1つのオプションは、リモートドメインのホスト名を「マスク」するように独自のドメインにCNAMEレコードを設定することです。

0
frogstarr78

これは、正しい引数を指定してcurlを呼び出し、curl出力を返すWebサーバーセットアップローカルを使用して実行することもできます。

app.rb

require 'sinatra'
require 'curb'

set :views,lambda {"views/"+self.name.to_s.downcase.sub("controller","")}
set :haml, :layout => :'../layout', :format => :html5, :escape_html=>true
disable :raise_errors

get '/data/:brand' do
  data_link =  "https://externalsite.com/#{params[:brand]}"
  c = Curl::Easy.perform(data_link)
  c.body_str
end

Ajaxリクエストをlocalhost:4567/data/somethingに送信すると、externalsite.com/somethingから結果が返されます。

0
Pablo Jomer