web-dev-qa-db-ja.com

ローカルファイルシステムの回避Chrome Access-control-allow-Origin?

私はここで他の同じOriginポリシーのトピックをSOで読みましたが、ローカルファイルシステムに関連する解決策を見たことがありません。

ローカルで提供する必要のある(ゆるい言葉で言えば)Webアプリがあります。ユーザーがWebページで何をしているかに応じて、ユーザーがページをロードした後に大量のデータをロードしようとしています。 Firefox 3.5およびIE8では、jQueryのAJAX()およびGetScript()メソッドを使用してこれを行うことができますが、Chromeでは、これは同じ生成元ポリシーのために失敗します。

XMLHttpRequestを読み込めませんfile://test/testdir/test.js。 Origin nullは許可されませんby Access-Control-Allow-Origin

これは、私が次のような単純なことをすると発生します

$.getScript("test.js");

これはIE&Firefoxで完全に機能します。

これについてたくさん読んだ後、私はドキュメントの先頭に直接書いてみることにしました。 Chromeのコンソールで、次のように入力しました:

var head = document.getElementsByTagName("head")[0];  
var script =document.createElement('script');   
script.id = 'uploadScript';  
script.type = 'text/javascript';  
script.src = "upload.js";   
head.appendChild(script);

これは、コンソールに貼り付けると正常に機能します-<script...test.js</script>要素がヘッドに追加され、評価され、コンテンツがDOMにロードされます。

このコードを関数呼び出しに入れるまで、これは成功したと思いました。同じコードを関数から呼び出すと、要素がに追加されますが、JavaScriptファイルは評価されません。理由がわかりません。 Chromeのコンソールを使用して、要素をに追加しているメソッドで実行を停止し、上記のコードを実行しても、評価されません。ただし、実行の一時停止を解除してまったく同じコードを実行すると(コンソールウィンドウに貼り付けて)、機能します。これを説明するのに途方に暮れています。これまでに誰かがこれに対処したことがありますか?

私は以下のSO=投稿を読みましたが、それらは私が抱えている問題を説明していません:

同じ起源のポリシーを回避する方法
XMLHttpRequest Origin nullは許可されていませんfile:///からfile:///へのAccess-Control-Allow-Origin(サーバーレス)
クロスサイトXMLHttpRequest

繰り返しますが、私の最後の手段は、Webページのロード時にすべてのデータをロードすることです。これにより、Webページのロードに最大10秒の遅延が発生し、アプリのユーザーの90%には不要になります。

提案/代替案をありがとう!!!

28
user210099

I think理解した。

本当に必要なのは、_<script>_タグにコールバックを追加することだけでした。最終コード:

Nextという名前の要素があるので、$("#next").click()関数には次のコードがあります。これは、「次へ」をクリックした場合にのみ実行されます。

_//remove old dynamically written script tag-    
       var old = document.getElementById('uploadScript');  
   if (old != null) {  
     old.parentNode.removeChild(old);  
     delete old;  
   } 

   var head = document.getElementsByTagName("head")[0];  
   script = document.createElement('script');  
   script.id = 'uploadScript';  
   script.type = 'text/javascript';  
   script.src = 'test/' + scope_dir + '/js/list.js';  
   script.onload = refresh_page;    
   head.appendChild(script);  


function refresh_page(){  
   //perform action with data loaded from the .js file.  
}  
_

これは機能しているようで、ChromeがjQuery関数を使用しようとしたときに遭遇したaccess-control-allow-Originポリシーを回避しながら、ローカルファイルシステムの.jsファイルを動的にロードすることを許可します。

4
user210099

わかりました。いじくり回したり、時間を無駄にしたりしました。しかし、私はそれを考え出した。私の最後の答えの解決策は、ChromeとMozillaでうまく機能します。 IEはonloadイベントを発生させないため、祝福されたIEでは機能しません。このファイルのすべてのonloadを処理したと見なされ、別のonloadを実行することはできません。 。ただし、IEは、JQuery getScript関数(Chromeがccess-control-allow- Originのポリシー)-これを機能させるには、JQueryライブラリが必要になります。

function getMyText(){
    var url='mylocalfile.js';
    if (jQuery.support.scriptEval) { 
        var old = document.getElementById('uploadScript');  
        if (old != null) {  
             old.parentNode.removeChild(old);  
             delete old;  
            } 
        var head = document.getElementsByTagName("head")[0]; 
        var script = document.createElement('script');
        script.id = 'uploadScript';
        script.type = 'text/javascript';
        script.onload = refresh_page; 
        script.src = url; 
        head.appendChild(script);  
    } else {
       $.getScript(url,function(){
            refresh_page();
      });
     }
}

function refresh_page() {
    alert(mytext);
}

これらすべてにおいて、mylocaltext.jsはすべてのHTMLを変数mytextのコンテンツとして定義します。醜いですが、動作します。 jQuery.support.scriptEvalは、DOMが変更された場合にonloadイベントを発生させるインテリジェントなブラウザーに対してtrueです。 IEしないので、.getScriptに送信されます。Chromeと他の人が行うので、逆の方法で送信されます。とにかく、これはローカルファイルで機能します。

2
peter

興味深いですが、同じ方法を使用してHTMLファイル全体をロードするにはどうすればよいですか?あなたと同様の問題-ユーザーが何を表示したいかに応じて、私は何百ものHTMLファイルをWebページに含めたいと思っています。このテクニックを使用して、次のようなHTMLページ全体をロードできるようです。

script.id = 'uploadScript';
script.type = 'text/html';
script.src = url; 
script.onload = refresh_page; 
head.appendChild(script);  

つまり、HTMLでロードするように指示します。コンソールからそれをページにロードしていることがわかり、「リソースはスクリプトとして解釈されましたが、MIMEタイプtext/htmlで転送されました」というメッセージが表示されます。しかし、スクリプトに読み込まれて保持されているHTMLを取得する方法を理解できません。

1
peter