Javascript 获取对本地文件的请求不起作用
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/50007055/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Fetch request to local file not working
提问by Javier
I'm trying to make a request in a local file, but I don't know when I try to do on my computer show me an error. Is possible make a fetch to a file inside your project?
我正在尝试在本地文件中发出请求,但我不知道何时尝试在我的计算机上执行显示错误。是否可以获取项目中的文件?
 // Option 1
 componentDidMount() {
     fetch('./movies.json')
     .then(res => res.json())
     .then((data) => {
        console.log(data)
     });
 }
 error: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 at App.js: 10 -->  .then(res => res.json())
 // Option 2
 componentDidMount() {
    fetch('./movies.json', {
       headers : { 
         'Content-Type': 'application/json',
         'Accept': 'application/json'
       }
    })
   .then( res => res.json())
   .then((data) => {
        console.log(data);
   });
 }
 error1: GET http://localhost:3000/movies.json 404 (Not Found) at App.js:15 --> fetch('./movies.json', {
 error2: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 at App.js: 10 -->  .then(res => res.json())
 // This works
 componentDidMount() {
   fetch('https://facebook.github.io/react-native/movies.json')
   .then( res => res.json() )
   .then( (data) => {
      console.log(data)
   })
 }
采纳答案by patelarpan
Your JSON file needs to be served by the server so you need the express server (or any other). In this example we are using using express.
您的 JSON 文件需要由服务器提供服务,因此您需要快速服务器(或任何其他服务器)。在这个例子中,我们使用的是express。
Note:you can also download git repo
注意:您也可以下载git repo
App.js File
App.js 文件
import React, { Component } from 'react';
class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }
  componentDidMount() {
    const myHeaders = new Headers({
      "Content-Type": "application/json",
      Accept: "application/json"
    });
    fetch("http://localhost:5000/movie", {
      headers: myHeaders,
    })
      .then(response => {
        console.log(response);
        return response.json();
      })
      .then(data => {
        console.log(data);
        this.setState({ data });
      });
  }
  render() {
    return <div className="App">{JSON.stringify(this.state.data)}</div>;
  }
}
export default App;
server.js
服务器.js
var express = require("express");
var data = require('./movie.json'); // your json file path
var app = express();
app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});
app.get("/movie", function(req, res, next) {
  res.send(data);
});
app.listen(5000, () => console.log('Example app listening on port 5000!'))
回答by Angelos Chalaris
You are trying to serve a static file with a fetch command, which inherently requires the file to be served by a server. To resolve the issue, you have a few options available to you. I am going to outline the two that are most commonly suggested for such a thing:
您正在尝试使用 fetch 命令提供静态文件,该命令本质上要求该文件由服务器提供。要解决此问题,您可以使用几个选项。我将概述最常建议用于此类事情的两个:
- Use Node.js and something like expressjsto host your own server that serves the file you want to fetch. While this procedure might require more effort and time, it is certainly more customizable and a good way to learn and understand how fetching from a backend works.
 - Use something like Chrome Web Serverto easily set up a very simple server to serve your file on your local network. Using this method, you have very little control over what you can do with said web server, but you can quickly and easily prototype your web application. However, I doubt there's a way to move this method to production.
 
- 使用 Node.js 和诸如expressjs 之类的东西来托管您自己的服务器,该服务器为您要获取的文件提供服务。虽然此过程可能需要更多的精力和时间,但它肯定更具可定制性,并且是学习和理解从后端获取如何工作的好方法。
 - 使用Chrome Web Server 之类的东西可以轻松设置一个非常简单的服务器,以便在本地网络上提供您的文件。使用这种方法,您几乎无法控制您可以使用所述 Web 服务器执行的操作,但是您可以快速轻松地构建您的 Web 应用程序原型。但是,我怀疑是否有办法将这种方法应用于生产。
 
Finally, there are other options where you can upload one or more files online and fetch them from an external URL, however this might not be the optimal strategy.
最后,还有其他选项可以让您在线上传一个或多个文件并从外部 URL 获取它们,但这可能不是最佳策略。
回答by Lex Soft
Try to place your json file in the public folder like so :
尝试将您的 json 文件放在公共文件夹中,如下所示:
public/movies.json
公共/movies.json
and then fetch using
然后使用
fetch('./movies.json')
or
或者
fetch('movies.json')
I have experienced the same problem previously. When I place the json file in the public folder, problem is solved. When using fetch, React normally reads asset/resources files in the public folder.
我以前遇到过同样的问题。当我将 json 文件放在 public 文件夹中时,问题就解决了。使用 fetch 时,React 通常会读取 public 文件夹中的资产/资源文件。
回答by vm909
My go-to approach is to use express-generatorto set up a quick local server, then run ngrok(free tier is fine) and point your app to the url it creates. This has the advantage of letting you easily test your fetching in the iOS simulator or Android emulator, as well as on a device not tethered to your computer. Plus, you can also send the url to people testing your app. Of course, there would need to be a way for them to manually input that url so the app could set it as the fetch endpoint.
我的首选方法是使用express-generator设置一个快速的本地服务器,然后运行ngrok(免费层很好)并将您的应用指向它创建的 url。这样做的好处是让您可以轻松地在 iOS 模拟器或 Android 模拟器中以及未连接到计算机的设备上测试您的抓取。此外,您还可以将 url 发送给测试您的应用程序的人。当然,他们需要有一种方法来手动输入该 url,以便应用程序可以将其设置为 fetch 端点。
回答by Charls Dzul
You can place your json file in the public folder. In your React component you can use userEffect (). You don't need Express.js for this case.
您可以将 json 文件放在 public 文件夹中。在您的 React 组件中,您可以使用 userEffect ()。对于这种情况,您不需要 Express.js。
React.useEffect(() => { 
   fetch("./views/util/cities.json")
      .then(function(response) {
        return response.json();
      })
      .then(function(myJson) {
        console.log(myJson);
      });
  });
回答by khanna
I got it working rather very simple way - no express / webserver really needed. Just do :
我让它以非常简单的方式工作 - 真的不需要快递/网络服务器。做就是了 :
import data from '../assets/data.json';
and use the json data like this (say if it is a JsonArray) :
data.map(movie... 
并使用这样的 json 数据(假设它是一个 JsonArray):
 data.map(movie...
Do this in App.jsor some other class extending React.Component,
在App.js或其他一些扩展类中执行此操作React.Component,
回答by DJJ
Say that i have the following file test.html
说我有以下文件 test.html
 <html>
   <head>
 <meta charset="UTF-8" />
 </head>
 <body>
 <script> 
 var depdata;
 depdata =  fetch("test1.geojson")
.then((data) => {
    return data;
});
 depdata.then(function(data) {console.log(data)})
   </script>
 </body>
 </html>
When access the file in the firefox through file://... I get the following error:
当通过 file:// 访问 firefox 中的文件时,我收到以下错误:
  Cross-Origin Request Blocked:....
When I followed the error on firefox I got the following explanation
当我在 Firefox 上关注错误时,我得到了以下解释
CORS requests may only use the HTTPS URL scheme, but the URL specified by the request is of a different type. This often occurs if the URL specifies a local file, using a file:/// URL.
To fix this problem, simply make sure you use HTTPS URLs when issuing requests involving CORS, such as XMLHttpRequest, Fetch APIs, Web Fonts (@font-face), and WebGL textures, and XSL stylesheets.
CORS 请求可能只使用 HTTPS URL 方案,但请求指定的 URL 是不同类型的。如果 URL 使用 file:/// URL 指定本地文件,则通常会发生这种情况。
要解决此问题,只需确保在发出涉及 CORS 的请求时使用 HTTPS URL,例如 XMLHttpRequest、Fetch API、Web 字体 (@font-face)、WebGL 纹理和 XSL 样式表。
So the as far as I understand we just need to access the test.html through HTTP. The most straight forward way around this problem was the python simple http server. In the terminal.
所以据我所知,我们只需要通过HTTP. 解决这个问题的最直接的方法是 python 简单的 http 服务器。在终端。
> cd directory of the project.
> python3 -m http.server 8000 --bind 127.0.0.1 
Then in the browser:
然后在浏览器中:
http://localhost:8000/test.html

