laravel 类型错误:“尝试获取资源时出现网络错误。”

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/51701630/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 17:57:31  来源:igfitidea点击:

TypeError: "NetworkError when attempting to fetch resource."

reactjslaravelapicorsfetch

提问by Sagar Gautam

I've found a lot of question similar to my problem but I don't get solution that's why I've asked here.

我发现了很多与我的问题类似的问题,但我没有得到解决方案,这就是我在这里问的原因。

I've just started learning front end development using React. I've made separate app for front end and backend running at different ports.

我刚刚开始学习使用 React 进行前端开发。我为在不同端口运行的前端和后端制作了单独的应用程序。

Backend : Laravel framework app running at incomeexpense.stacklearning.com/

后端:Laravel 框架应用程序运行于 incomeexpense.stacklearning.com/

Frontend : React app running at localhost:3000/

前端:React 应用程序运行于 localhost:3000/

I've a form like this:

我有一个这样的表格:

import React,{Component} from 'react';

export default class Register extends Component{
constructor(props){
    super(props);

    this.state = {
        name: '',
        email: '',
        password: '',
        confirm_password: ''
    }
}

updateInput = (event) =>{
    const name = event.target.name;
    const value = event.target.value;

    this.setState({[name]: value});
}

handleSubmit = (event)=>{
    event.preventDefault();
    fetch('http://incomeexpense.stacklearning.com/api/users', {
        method: 'POST',
        body: JSON.stringify({
            name: this.state.name,
            email: this.state.email,
            password: this.state.password,
            confirm_password: this.state.confirm_password
        }),
        headers: {
            "Content-Type": "application/json",
            "Origin": "localhost:3000",
        }
    }).then(function (response) {
        console.log(response);
    },function (error) {
        console.log(error);
    });
}

render(){
    return(
        <div className="limiter">
            <div className="container-login100">
                <div className="wrap-login100 p-l-85 p-r-85 p-t-55 p-b-55">
                    <form className="login100-form validate-form flex-sb flex-w" onSubmit={this.handleSubmit}>
                        <span className="login100-form-title p-b-32">
                            Sign Up
                        </span>
                        <span className="txt1 p-b-11">
                            Name
                        </span>
                        <div className="wrap-input100 validate-input m-b-36" >
                            <input className="input100" type="text" name="name" value={this.state.name} onChange={this.updateInput}/>
                            <span className="focus-input100"></span>
                        </div>
                        <span className="txt1 p-b-11">
                            Email
                        </span>
                        <div className="wrap-input100 validate-input m-b-36">
                            <input className="input100" type="text" name="email" value={this.state.email} onChange={this.updateInput}/>
                            <span className="focus-input100"></span>
                        </div>
                        <span className="txt1 p-b-11">
                            Password
                        </span>
                        <div className="wrap-input100 validate-input m-b-36">
                            <input className="input100" type="password" name="password" value={this.state.password} onChange={this.updateInput}/>
                            <span className="focus-input100"></span>
                        </div>
                        <span className="txt1 p-b-11">
                            Confirm Password
                        </span>
                        <div className="wrap-input100 validate-input m-b-18">
                            <input className="input100" type="password" name="confirm_password" value={this.state.confirm_password} onChange={this.updateInput}/>
                            <span className="focus-input100"></span>
                        </div>
                        <div className="container-login100-form-btn">
                            <button className="login100-form-btn">
                                Register
                            </button>
                        </div>
                        <div className="flex-sb-m w-full p-b-48 m-t-60 text-center">
                            <label>
                                Already have an account ?
                                <a className="txt3 m-l-5" href="/login">
                                    Sign In Now
                                </a>
                            </label>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    );
}
}

I've following routes,

我有以下路线,

Route::middleware('auth:api')->get('/user', function (Request $request) {
    return $request->user();
});

Route::post('users',array( 'middleware'=>'cors','uses'=>'Auth\RegisterController@registerUser'));
Route::get('users',array( 'middleware'=>'cors','uses'=>'Auth\RegisterController@getUsers'));

Here is CORS middleware,

这是 CORS 中间件,

<?php

namespace App\Http\Middleware;

use Closure;

class CORS
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @return mixed
     */
    public function handle($request, Closure $next)
    {
        header('Access-Control-Allow-Origin: http://localhost:3000/');
        header('Access-Control-Allow-Credentials: true');

        // ALLOW OPTIONS METHOD
        $headers = [
            'Access-Control-Allow-Methods'=> 'POST, GET, OPTIONS, PUT, DELETE',
            'Access-Control-Allow-Headers'=> 'Content-Type, X-Auth-Token, Origin'
        ];

        if($request->getMethod() == "OPTIONS") {
            // The client-side application can set only headers allowed in Access-Control-Allow-Headers
            return Response::make('OK', 200, $headers);
        }

        $response = $next($request);
        foreach($headers as $key => $value)
            $response->header($key, $value);

        return $next($request);
    }
}

Finally here is user creating function

最后这里是用户创建功能

protected function create(array $data)
{
    return User::create([
        'name' => $data['name'],
        'email' => $data['email'],
        'password' => bcrypt($data['password']),
    ]);
}

protected function registerUser(Request $request)
{
    $data = $request->all();
    return response()->json($this->create($data));
}

When I send the post request from react app following error is shown at console

当我从 react app 发送 post 请求时,控制台显示以下错误

Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://incomeexpense.stacklearning.com/api/users. (Reason: CORS header ‘Access-Control-Allow-Origin' missing).

TypeError: "NetworkError when attempting to fetch resource." Register.js:39 Cross-Origin Request Blocked:

The Same Origin Policy disallows reading the remote resource at http://incomeexpense.stacklearning.com/api/users. (Reason: CORS request did not succeed).

跨域请求被阻止:同源策略不允许读取http://incomeexpense.stacklearning.com/api/users 上的远程资源。(原因:缺少 CORS 标头“Access-Control-Allow-Origin”)。

类型错误:“尝试获取资源时出现网络错误。” Register.js:39 跨域请求被阻止:

同源策略不允许读取http://incomeexpense.stacklearning.com/api/users 上的远程资源。(原因:CORS 请求没有成功)。

I know this error is due to different domain and browser prevent resource access to different domain.

我知道这个错误是由于不同的域和浏览器阻止了对不同域的资源访问。

I just want to know what I need need to do at front and at back end to make things right

我只想知道我需要在前端和后端做什么才能把事情做好

PS: back end code works perfectly while sending request from postman.

PS:后端代码在从邮递员发送请求时完美运行。

回答by Johnathan Maravilla

URI Schema Mismatch

URI 架构不匹配

The Originrequest header set within the headersinterface of your fetch request contains the host: localhost:3000. The Access-Control-Allow-Origin CORS header that is configured within the CORS middleware contains the host: http://localhost:3000/. The URI scheme/host/port tuple defined must be an exact match in both the fetch request and CORS middlewares.

Originheaders您的 fetch 请求的接口中设置的请求标头包含 host: localhost:3000。在 CORS 中间件中配置的 Access-Control-Allow-Origin CORS 标头包含主机:http://localhost:3000/. 在获取请求和 CORS 中间件中,定义的 URI 方案/主机/端口元组必须完全匹配。

Change both of your URLs to http://localhost:3000

将您的两个网址更改为 http://localhost:3000

See: Fetch Spec, CORS Specand CORS for Developers

请参阅:Fetch Spec, CORS SpecCORS for Developers

Chrome Bug

铬错误

Just to note, Chrome does not support CORS Requests for localhost. You can find the documented Chrome bug here. There are some workarounds listed within the bug, if need.

请注意,Chrome 不支持localhost. 您可以在此处找到记录在案的 Chrome 错误。如果需要,错误中列出了一些解决方法。