Chrome - Fetch API 无法加载文件。如何解决?
Posted
技术标签:
【中文标题】Chrome - Fetch API 无法加载文件。如何解决?【英文标题】:Chrome - Fetch API cannot load file. How to workaround? 【发布时间】:2018-10-02 22:30:40 【问题描述】:我有以下两个文件:
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
正确显示。
但是当我在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)
您有什么办法可以像在Mozilla Firefox
上一样打开Google Chrome
上的本地文件吗?
如果我必须做一些调整:
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)
谢谢!
【问题讨论】:
您的问题的答案在 Chrome 提供的错误消息中。出于安全原因,Chrome 不允许您通过file:///...
加载本地文件。如果这是您正在开发的仅在本地使用的应用程序,那么您可以下载一个 Chrome 应用程序,该应用程序会在某个本地目录中为您创建一个 Web 服务器。 Chrome 的 Web 服务器是 Google 在其代码实验室工作时建议使用的服务器
没有chrome://flags/
调整,只有命令行调整。使用命令行选项启动 chrome,允许 file:///
页面访问 file:///
这样的资源 - 我不知道该选项,快速谷歌搜索应该会有所帮助
现在 Chrome 的 fetch
似乎无法与 file://
URL 方案一起使用。你考虑过 XHR 吗?或者,更好的是,使用本地 http 服务器?
@Jaromanda,谢谢,成功了
【参考方案1】:
对于 chrome,您仍然需要 --allow-file-access-from-files
(我建议安装 separate chrome 并将其仅用于这些项目以保持安全),但对于 XMLHttpRequest
的 file://
请求只需填充 fetch()
:
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://
请求)调用普通的fetch()
,并且
会将绝对路径 (/root/bob.html
) 替换为相对于当前路径的路径(因为这会危险地评估为 C:\
或等效路径)
如果您的 index.html
实际上不是项目的根目录,请将 path
设置为其他值。
如果您需要对 init 或 text()
以外的任何支持,则需要添加它。
明确的file://
请求不会被满足,这是故意的,但如果你真的知道你在做什么,你就会知道如何让这个工作为你工作,如果你不知道你不应该。
如果您要对多个文件执行此操作,以下内容很有用。将'./'
换成document.currentScript.getAttribute('data-root')
。现在您可以将该 sn-p 放入它自己的文件中,例如 filesystemHelper.js
,然后在各个文件中像这样调用:
<script src="../filesystemHelper.js" data-root="../"></script>
相当时髦。
【讨论】:
在使用fetch()
运行代码之前将其粘贴在<script>
标记中
请注意,这个 shim 有一些限制:它不包括 ok
和其他 Response
成员。看起来Windows上的Chrome也不会根据文件扩展名猜测MIME类型,至少.json
XMLHttpRequest
不是也被 Chrome 本地屏蔽了吗?此错误仍然出现:Access to XMLHttpRequest at 'x' from origin 'null' has been blocked by CORS policy
。是我做错了,还是不能开箱即用?以上是关于Chrome - Fetch API 无法加载文件。如何解决?的主要内容,如果未能解决你的问题,请参考以下文章
Fetch API 无法加载“.php”本地文件 - React JS + PHP
Fetch API 无法加载 URL 方案对于 CORS 请求必须是“http”或“https”