TypeError:“尝试获取资源时出现NetworkError。”

时间:2018-08-06 06:23:05

标签: reactjs laravel api cors fetch

我发现了很多与我的问题类似的问题,但是我没有找到解决方案,这就是为什么我在这里问到。

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

后端:运行在incomeexpense.stacklearning.com/上的Laravel框架应用

前端:运行在localhost:3000/上的React应用

我有这样的表格:

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

我正在遵循路线,

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'));

这是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);
    }
}

最后是用户创建功能

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

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

  

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

     

TypeError:“尝试获取资源时出现NetworkError。” Register.js:39   跨域请求被阻止:

     

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

我知道此错误是由于不同的域引起的,浏览器阻止了对不同域的资源访问。

我只想知道在前端和后端需要做些什么才能使事情正确

PS:后端代码在发送邮递员的请求时非常有效。

1 个答案:

答案 0 :(得分:0)

URI模式不匹配

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

将两个URL都更改为http://localhost:3000

请参阅:Fetch SpecCORS SpecCORS for Developers

Chrome浏览器错误

请注意,Chrome不支持localhost的CORS请求。您可以找到已记录的Chrome错误here。如果需要,该错误中列出了一些解决方法。