Chrome - Fetch API无法加载文件。如何解决?

时间:2018-04-22 23:08:06

标签: javascript google-chrome firefox 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

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

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

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

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作为建议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)

谢谢!

1 个答案:

答案 0 :(得分:4)

对于Chrome,您仍然需要--allow-file-access-from-files(并且我建议安装separate chrome并仅将其用于这些项目以确保安全),但是只需对fetch()填充XMLHttpRequest对于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语句),
  • 为未指定协议的所有网址调用普通的fetch()(并因此请求非file://的请求),并且
  • 将相对于当前路径的绝对路径(/root/bob.html)替换为绝对路径({危险地评估为C:\或等效路径)

如果您的path实际上不在项目的根目录,请将index.html设置为其他内容。
如果您需要对inittext()以外的任何支持,则需要添加它。
明确的file://请求不会得到满足,这是有目的的,但是如果您真的确实知道自己在做什么,那么您将知道如何为您完成这项工作,如果您不这样做,


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

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

漂亮时髦。