web-dev-qa-db-fra.com

Chrome - L'API Fetch ne peut pas charger le fichier. Comment contourner?

J'ai les deux fichiers suivants:

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.

Quand j'ouvre le Mozilla Firefox le fichier: README.html via ce local URI:

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

cela fonctionne comme prévu, je veux dire, le texte du fichier: info.txt s'affiche correctement.

Mais quand j'ouvre le même URI sur Google Chrome J'obtiens un écran vide et l'erreur suivante sur la 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)

Avez-vous ce que je peux faire pour pouvoir ouvrir des fichiers locaux sur Google Chrome comme je peux le faire sur Mozilla Firefox?

Si je dois faire quelques ajustements sur:

chrome://flags/

c'est acceptable pour moi.

[~ # ~] modifier [~ # ~]

J'ai essayé de lancer Google Chrome à partir de la ligne de commande avec l'indicateur: --allow-file-access-from-files comme recommandé ici mais maintenant j'obtiens l'erreur suivante:

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)

Merci!

10
davidesp

Pour chrome vous avez toujours besoin de --allow-file-access-from-files (Et je recommande d'installer un chrome séparé et de l'utiliser uniquement pour que ces projets restent sécurisés), mais juste du shim fetch() pour XMLHttpRequest pour file:// requêtes:

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();
        })
    );
}

Cette cale va;

  • activer uniquement pour les fichiers html ouverts localement (instruction if externe),
  • appelez la fetch() normale pour toute URL qui ne spécifie pas de protocole (et donc pas de requêtes - file://), et
  • remplacera les chemins absolus (/root/bob.html) par ceux relatifs au chemin actuel (car cela serait dangereusement évalué à C:\ ou équivalent)

Définissez path sur autre chose si votre index.html N'est pas réellement à la racine du projet.
Si vous avez besoin de support pour init , ou autre chose que text(), vous devrez l'ajouter.
Les demandes explicites de file:// Ne seront pas satisfaites, c'est exprès, mais si vous vraiment savez vraiment ce que vous faites , vous saurez comment faire fonctionner cela pour vous, et si vous ne le faites pas, vous ne devriez pas.


Ce qui suit est utile si vous comptez le faire pour plusieurs fichiers. Remplacez './' Par document.currentScript.getAttribute('data-root'). Maintenant, vous pouvez mettre cet extrait dans son propre fichier, dire filesystemHelper.js, Et l'appeler ainsi dans les différents fichiers:

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

Assez chic.

2
Hashbrown