Chrome - Fetch API 无法加载文件.如何解决? [英] Chrome - Fetch API cannot load file. How to workaround?

查看:101
本文介绍了Chrome - Fetch API 无法加载文件.如何解决?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下两个文件:

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 上打开文件:README.html 通过这个本地 URI:

When I open on Mozilla Firefox the file: README.html through this local URI:

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

它按预期工作,我的意思是,文件中的文本:info.txt 显示正确.

it works as expected, I mean, the text on file: info.txt is displayed properly.

但是当我在 Google Chrome 上打开相同的 URI 时,我得到一个空白屏幕,并且控制台上出现以下错误:

But when I open the same URI on Google Chrome I get a blank screen and the following error on the console:

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)

你有什么办法让我可以像在 Mozilla Firefox 上一样在 Google Chrome 上打开本地文件?

Do you have what can I do so I can open local files on Google Chrome as I can do on Mozilla Firefox?

如果我必须做一些调整:

If I have to do some tweak on:

chrome://flags/

这对我来说是可以接受的.

that's acceptable for me.

编辑

我尝试从带有以下标志的命令行启动 Google Chrome:--allow-file-access-from-files 按照推荐的 此处 但现在出现以下错误:

I tried launching Google Chrome from the command line with the flag: --allow-file-access-from-files as recommended here but now I get the following error:

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)

谢谢!

推荐答案

对于 chrome 你仍然需要 --allow-file-access-from-files(我建议安装一个 单独的 chrome 并仅将其用于这些项目以保持安全),但只是 shim fetch() 用于 XMLHttpRequest 用于 file:// 请求:

For chrome you still need --allow-file-access-from-files (and I recommend installing a separate chrome and using it solely for these projects to stay secure), but just shim fetch() for XMLHttpRequest for file:// requests:

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 语句),
  • 为任何未指定协议的 url(因此非 file:// 请求)调用普通的 fetch(),并且
  • 会将绝对路径 (/root/bob.html) 替换为相对于当前路径的路径(因为这会危险地评估为 C: 或等效路径)
  • only activate for html files opened locally (outer if statement),
  • call the normal fetch() for any url that doesn't specify protocol (and thus non-file:// requests), and
  • will replace absolute paths (/root/bob.html) with ones relative to the current path (since that would dangerously evaluate to C: or equivalent)

如果您的 index.html 实际上不是项目的根目录,请将 path 设置为其他内容.
如果您需要对 init 或任何内容的支持除了 text(),您需要添加它.
显式的 file:// 请求不会被满足,这是故意的,但如果你真的知道你在做什么,你就会知道如何让这个工作你,如果你不这样做,你就不应该.

Set path to something else if your index.html isn't actually at the root for the project.
If you need support for init, or anything other than text(), you'll need to add it.
Explicit file:// requests wont be fulfilled, that's on purpose, but if you really do know what you're doing, you'll know how to make this work for you, and if you don't you shouldn't.

如果您要为多个文件执行此操作,以下内容很有用.将 './' 换成 document.currentScript.getAttribute('data-root').现在您可以将该代码片段放入其自己的文件中,例如 filesystemHelper.js,并在各种文件中像这样调用:

The following is useful if you're going to be doing this for multiple files. Swap out './' for document.currentScript.getAttribute('data-root'). Now you can put that snippet into its own file, say filesystemHelper.js, and call like so in the various files:

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

相当时髦.

这篇关于Chrome - Fetch API 无法加载文件.如何解决?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆