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
:
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
как рекомендовано здесь, но теперь я получаю следующую ошибку:
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)
Спасибо!
0 ответов
Для хрома еще нужен --allow-file-access-from-files
(и я рекомендую установить отдельный хром и использовать его исключительно для этих проектов, чтобы оставаться в безопасности), но просто прокладывайте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()
для любого URL-адреса, который не указывает протокол (и, следовательно, не-file://
запросы), и - заменит абсолютные пути (
/root/bob.html
) с единицами относительно текущего пути (так как это опасноC:\
или эквивалент)
Задавать path
к чему-то другому, если ваш index.html
на самом деле не лежит в основе проекта.
Если вам нужна поддержка init или что-то еще, кромеtext()
, вам нужно будет его добавить.
Явныйfile://
запросы не будут выполняться, это сделано специально, но если вы действительно знаете, что делаете, вы будете знать, как заставить это работать на вас, а если вы этого не сделаете, вам не следует этого делать.
Следующее полезно, если вы собираетесь делать это для нескольких файлов. Поменять'./'
за document.currentScript.getAttribute('data-root')
. Теперь вы можете поместить этот фрагмент в отдельный файл, напримерfilesystemHelper.js
, и вызываем в разных файлах так:
<script src="../filesystemHelper.js" data-root="../"></script>
Довольно шикарно.