web-dev-qa-db-ja.com

Chrome=-Fetch APIがファイルを読み込めません。回避策は?

次の2つのファイルがあります。

index.html

<html>
<head>
<meta charset="utf-8" />
<title>Web Page</title>
<style type="text/css">
.text {
    display: inline-block;
    font-family: tahoma;
    font-size: 14px;
    max-width: 400px;
    background-color: #ddedff;
    padding: 10px;
    text-align: justify;
}
</style>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script type="text/javascript">
$(function(){
    get_data('info.txt');
});
function get_data(file) {
    var request = new Request(file);
    fetch(request).then(function(response) {
        return response.text().then(function(text) {
            $('.text').html(text);
        });
    });
}
</script>
</head>
<body>
    <div class="text"></div>
</body>
<html>

info.txt

Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.

Mozilla Firefoxでファイルを開くと、このローカルURIを介してREADME.html

file:///C:/testing/README.html

期待どおりに機能します。つまり、ファイル:info.txtのテキストは正しく表示されます。

しかし、Google Chromeで同じURIを開くと、空白の画面が表示され、コンソールに次のエラーが表示されます。

README.html:26 Fetch API cannot load file:///C:/testing/README.md. URL scheme must be "http" or "https" for CORS request.
get_data @ README.html:26
README.html:26 Uncaught (in promise) TypeError: Failed to fetch
    at get_data (README.html:26)
    at HTMLDocument.<anonymous> (README.html:21)
    at l (jquery.min.js:2)
    at c (jquery.min.js:2)

Google Chromeでできるように、Mozilla Firefoxでローカルファイルを開くことができるように、私にできることはありますか?

私はいくつかの微調整を行う必要がある場合:

chrome://flags/

それは私には受け入れられます。

[〜#〜]編集[〜#〜]

コマンドラインからGoogle Chromeをフラグ付きで起動しようとしました:--allow-file-access-from-files as Recommended here しかし、今は次のエラーが発生します:

README.html:26 Fetch API cannot load file:///C:/testing/README.md. URL scheme "file" is not supported.
get_data @ README.html:26
README.html:26 Uncaught (in promise) TypeError: Failed to fetch
    at get_data (README.html:26)
    at HTMLDocument.<anonymous> (README.html:21)
    at l (jquery.min.js:2)
    at c (jquery.min.js:2)

ありがとう!

10
davidesp

chromeの場合、_--allow-file-access-from-files_が必要です(そして separate chrome をインストールして、これらのプロジェクトを安全に保つためだけに使用することをお勧めします)が、shimだけですfetch() for XMLHttpRequest for _file://_リクエスト:

_if (/^file:\/\/\//.test(location.href)) {
    let path = './';
    let orig = fetch;
    window.fetch = (resource) => ((/^[^/:]*:/.test(resource)) ?
        orig(resource) :
        new Promise(function(resolve, reject) {
            let request = new XMLHttpRequest();

            let fail = (error) => {reject(error)};
            ['error', 'abort'].forEach((event) => { request.addEventListener(event, fail); });

            let pull = (expected) => (new Promise((resolve, reject) => {
                if (
                    request.responseType == expected ||
                    (expected == 'text' && !request.responseType)
                )
                    resolve(request.response);
                else
                    reject(request.responseType);
            }));

            request.addEventListener('load', () => (resolve({
                arrayBuffer : () => (pull('arraybuffer')),
                blob        : () => (pull('blob')),
                text        : () => (pull('text')),
                json        : () => (pull('json'))
            })));
            request.open('GET', resource.replace(/^\//, path));
            request.send();
        })
    );
}
_

このシムはします。

  • ローカルで開かれたhtmlファイルに対してのみアクティブ化(外部ifステートメント)、
  • プロトコルを指定していない(したがって_file://_リクエストではない)URLに対して通常のfetch()を呼び出します。
  • 絶対パス(_/root/bob.html_)を現在のパスからの相対パスに置き換えます(これは_C:\_または同等のものと危険に評価されるため)

_index.html_が実際にプロジェクトのルートにない場合は、pathを別の値に設定します。
init 、またはtext()以外のサポートが必要な場合は、追加する必要があります。
明示的な_file://_要求は意図的に実行されませんが、本当にあなたが何をしているかを知っている場合、あなたはこれをあなたのために機能させる方法を知っています、そしてあなたがしなければあなたはそうすべきではありません。


以下は、複数のファイルに対してこれを行う場合に役立ちます。 _'./'_をdocument.currentScript.getAttribute('data-root')に置き換えます。これで、そのスニペットを独自のファイル、たとえば_filesystemHelper.js_に入れて、さまざまなファイルで次のように呼び出すことができます。

_<script src="../filesystemHelper.js" data-root="../"></script>
_

かなりおしゃれです。

2
Hashbrown