AJAXクロスドメインポリシーについて知っています。だから、ajax HTTPリクエストを介して " http://www.google.com "を呼び出すことはできません。結果は私のサイトのどこかにあります。
DataType "jsonp"で試しましたが、実際には動作しますが、構文エラーが表示されます(明らかに、受信したデータがJSON形式ではないため)
外部ドメインからデータを受信/表示する他の可能性はありますか? iFrameは同じポリシーに従いますか?
AJAXを使用してクロスドメインデータを取得する唯一の(簡単な)方法は、 Andy E のようにプロキシとしてサーバー側の言語を使用することです。 jQueryを使用して実装するには:
JQueryパーツ:
$.ajax({
url: 'proxy.php',
type: 'POST',
data: {
address: 'http://www.google.com'
},
success: function(response) {
// response now contains full HTML of google.com
}
});
そしてPHP(proxy.php):
echo file_get_contents($_POST['address']);
そのような単純な。スクレイピングされたデータを使用してできること、またはできないことだけに注意してください。
データを参照するページにスクリプトタグを動的に挿入する必要があります。 JSONPを使用すると、スクリプトがロードされたときにコールバック関数を実行できます。
[〜#〜] jsonp [〜#〜] のウィキペディアページには簡潔な例があります。スクリプトタグ:
<script type="text/javascript" src="http://domain1.com/getjson?jsonp=parseResponse">
</script>
parseResponse
への呼び出しにラップされたJSONデータを返します。
parseResponse({"Name": "Cheeso", "Rank": 7})
(domain1.comのgetjson
スクリプトの構成に依存)
タグを動的に挿入するコードは次のようになります。
var s = document.createElement("script");
s.src = "http://domain1.com/getjson?jsonp=parseResponse";
s.type = "text/javascript";
document.appendChild(s);
[〜#〜] yql [〜#〜] を使用して、独自のプロキシをホストする必要なくリクエストを実行できます。コマンドを実行しやすくするために、単純な関数を作成しました。
function RunYQL(command, callback){
callback_name = "__YQL_callback_"+(new Date()).getTime();
window[callback_name] = callback;
a = document.createElement('script');
a.src = "http://query.yahooapis.com/v1/public/yql?q="
+escape(command)+"&format=json&callback="+callback_name;
a.type = "text/javascript";
document.getElementsByTagName("head")[0].appendChild(a);
}
JQueryがある場合は、代わりに$ .getJSONを使用できます。
サンプルは次のとおりです。
RunYQL('select * from html where url="http://www.google.com/"',
function(data){/* actions */}
);
残念ながら(または幸いなことに)そうではありません。クロスドメインポリシーには理由があります。簡単に回避できる場合、セキュリティ対策としてはあまり効果的ではありません。 JSONP以外、唯一のオプションは 独自のサーバーを使用してページをプロキシする です。
Iframeでは、それらは同じポリシーの対象となります。もちろん、外部ドメインからのデータを表示することはできますが、それを操作することはできません。
このコードをクロスドメインAjax呼び出しに使用します。ここで複数のコードが役立つことを願っています。私はPrototypeライブラリを使用していますが、JQueryやDojoなどでも同じことができます:
ステップ1:新しいjsファイルを作成し、このクラスを内部に配置して、xss_ajax.jsという名前を付けました
var WSAjax = Class.create ({
initialize: function (_url, _callback){
this.url = _url ;
this.callback = _callback ;
this.connect () ;
},
connect: function (){
var script_id = null;
var script = document.createElement('script');
script.setAttribute('type', 'text/javascript');
script.setAttribute('src', this.url);
script.setAttribute('id', 'xss_ajax_script');
script_id = document.getElementById('xss_ajax_script');
if(script_id){
document.getElementsByTagName('head')[0].removeChild(script_id);
}
// Insert <script> into DOM
document.getElementsByTagName('head')[0].appendChild(script);
},
process: function (data){
this.callback(data) ;
}
}) ;
このクラスは、src属性がJSONデータプロバイダーをターゲットとする動的なスクリプト要素を作成します(実際には、JSON-Pは遠隔サーバーがこの形式でデータを提供する必要があるため::: call_back_function(// json_data_here)::スクリプトタグが作成されると、 JSONは関数として直接評価されます(ステップ2でコールバックメソッド名をサーバーに渡すことについて説明します)。この背後にある主な概念は、img要素のようなスクリプトがSOP制約に関係しないということです。
Step2:XHTTPRequestオブジェクトを使用するAJAXの代わりに、JSONを非同期的にプルしたいHTMLページ(これをAJAJ〜Asynchronous JAvascript + JSON :-)と呼びます)
//load Prototype first
//load the file you've created in step1
var xss_crawler = new WSAjax (
"http://your_json_data_provider_url?callback=xss_crawler.process"
, function (_data){
// your json data is _data and do whatever you like with it
}) ;
ステップ1でコールバックを覚えていますか?そのため、サーバーに渡し、そのメソッドに埋め込まれたJSONを返します。この場合、サーバーは評価可能なjavascriptコードxss_crawler.process(// the_json_data)を返します。xss_crawlerはWSAjaxクラスのインスタンスであることを思い出してください。サーバーコードはユーザーに依存します(ユーザーの場合)が、ほとんどのAjaxデータプロバイダーでは、パラメーターでコールバックメソッドを指定できます。 RubyのRailsで
render :json=>MyModel.all(:limit=>10), :callback => params[:callback],:content_type => "application/json"
これですべて、JSON形式のみのアプリ(ウィジェット、マップなど)から別のドメインからデータを取得できるようになりました。忘れないでください。
あなたの忍耐に感謝します:-)、コードのフォーマットに平和と申し訳ありませんが、うまく機能しません
いくつかの調査を行った後、この問題の唯一の「解決策」は以下を呼び出すことです:
if($.browser.mozilla)
netscape.security.PrivilegeManager.enablePrivilege('UniversalBrowserRead');
これにより、ユーザーにWebサイトの継続を許可するかどうかが尋ねられます。彼がそれを確認した後、データ型に関係なくすべてのajaxコールが実行されます。
これは、Mozillaブラウザーで機能します。IE <8、ユーザーは同様の方法でクロスドメインコールを許可する必要があり、一部のバージョンはブラウザーオプション内で構成する必要があります。
chrome/safari:今のところ、これらのブラウザの設定フラグは見つかりませんでした。
jSONPをデータ型として使用するのは良いことですが、私の場合、アクセスする必要があるドメインがその形式のデータをサポートしているかどうかはわかりません。
別のショットは、クロスドメインでも機能するHTML5 postMessageを使用することですが、ユーザーをHTML5ブラウザーに破滅させる余裕はありません。
Phpスクリプトを使用してリモートサーバーから回答を取得している場合は、最初に次の行を追加します。
header("Access-Control-Allow-Origin: *");
私の意見では、JSONPが最良の選択肢です。構文エラーが発生する理由を理解してください-受信したデータがJSONではないことを確認してください。それから多分あなたは何とか間違ったAPIを使用しています。
あなたが使用できる別の方法ですが、私はそれがあなたの場合に適用されるとは思わない、srcがあなたが呼び出したいドメインにあるページにiFrameを持っています。呼び出しを行わせてから、JSを使用してiFrameとページ間で通信します。これは、クロスドメインをバイパスしますが、呼び出したいドメインにiFrameのsrcがある場合のみです。
ここでは、空想やJSONを使用しなくても、簡単に実行できる方法を示します。
最初に、リクエストを処理するサーバー側スクリプトを作成します。 http://www.example.com/path/handler.php のようなもの
次のようなパラメータで呼び出します:.../handler.php?param1 = 12345&param2 = 67890
その中で、受信したデータを処理した後、output:
document.serverResponse('..all the data, in any format that suits you..');
// Any code could be used instead, because you dont have to encode this data
// All your output will simply be executed as normal javascript
次に、クライアント側のスクリプトで、次を使用します。
document.serverResponse = function(param){ console.log(param) }
var script = document.createElement('script');
script.src='http://www.example.com/path/handler.php?param1=12345¶m2=67890';
document.head.appendChild(script);
このアプローチの唯一の制限は、サーバーに送信できるパラメーターの最大長です。ただし、複数のリクエストをいつでも送信できます。
テクノロジーCORSを使用して、両方のサーバー(Javascriptが実行されているサーバーと外部APIサーバー)を構成できます。
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
p.s .:答え https://stackoverflow.com/a/37384641/6505594 もこのアプローチを提案しており、外部APIサーバーを他の全員に開放して呼び出しています。