reactjs Laravel API + React前端请求,Axios返回404 - Access-Control-Allow-Origin

qyyhg6bp  于 2023-06-22  发布在  React
关注(0)|答案(1)|浏览(110)

我正在尝试从React向Laravel API发出POST请求。当我在开发模式下发送请求时,请求是成功的,但当我在Apache 2上部署API(:8000)和前端(:80)时,请求被strict-mode-policy和CORS错误阻止,该错误表示我的请求缺少Access-Control-Allow-Origin和404作为响应。但是Laravel和React页面可以在浏览器中访问。我使用Axios进行请求。网站应该有相同的基本网址http://localhost我尝试了许多解决方案,但没有一个是为我工作。

Laravel 10.x cors

我看到许多用户建议您的中间件向服务器响应添加头。Laravel(conf/cors.php)中默认添加了类似的内容;我的档案是这样的

'paths' => ['http://127.0.0.1:8000','http://localhost','api/*', 'sanctum/csrf-cookie'],
    
    'allowed_methods' => ['*'],
    
    'allowed_origins' => ['*'],
    
    'allowed_origins_patterns' => [],
    
    'allowed_headers' => ['*'],
    
    'exposed_headers' => ['*'],
    
    'max_age' => 0,
    
    'supports_credentials' => false,

它在Kernel.php中注册为

protected $middlewareAliases = [
                 // 'cors' => \App\Http\Middleware\Cors::class, <- this is custom middleware not in use now
                'cors' => \Illuminate\Http\Middleware\HandleCors::class,
                'auth' => \App\Http\Middleware\Authenticate::class,
                ...
    
         protected $middleware = [
            // \App\Http\Middleware\Cors::class, <- This is custom 
    middleware not in use now
            \Illuminate\Http\Middleware\HandleCors::class,

这是我在使用CUSTOM中间件时在api.php中所拥有的

Route::group(['middleware'=>'cors','prefix'=>'api'], function () 
{
    Route::post('/signup',[AuthController::class, 'signup']);
    Route::post('/login',[AuthController::class, 'login']);
    Route::post('/logout',[AuthController::class, 'logout']);
    Route::post('/user/post',[PostController::class,'createPost']);
    Route::get('/user/post',[PostController::class,'getPostsInMonth']);
    
    Route::post('/media/upload',[UploadController::class,'upload']);

});

即使使用自定义中间件也没有成功

class Cors
    {
        public function handle(Request $request, Closure $next): Response
        {
            return $next($request)
                ->header('Access-Control-Allow-Origin', '*')
                ->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
                ->header('Access-Control-Allow-Headers', 'Content-Type, Authorization, Origin, X-Requested-With');
        }
    }

在Apache Laravel VirtualHost文件中添加header

<VirtualHost *:8000>
        ServerName website.com
        ServerAlias *.website.com
        ServerAdmin webmaster@localhost
        DocumentRoot .../laravel/public
        Header add Access-Control-Allow-Origin "*"
        Header add Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
        <Directory ".../laravel">
            Header set Access-Control-Allow-Origin "*"
            Header set Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept, Authorization"
            Order allow, deny
            Allow from all
            Require all granted
        </Directory>
    </VirtualHost>

React Apache VirtualHost文件看起来与Laravel文件非常相似
我没有成功:(

.htaccess in Laravel/public

<IfModule mod_headers.c>
        Header set Cross-Origin-Resource-Policy 'cross-origin'
        Header set Access-Control-Allow-Origin "*"
    </IfModule>

设置API地址作为代理

package.json中,我添加了这一行

"proxy": "http://localhost:8000",

我也试过使用react/src文件夹中的http-proxy-middleware包和setupProxy.js

const { createProxyMiddleware } = require('http-proxy-middleware');
    
    module.exports = function(app) {
     app.use(
        '/api/*',
        createProxyMiddleware({
          target: 'http://localhost:8000',
          changeOrigin: true,
        })
     );
    };

axios客户端脚本

import axios from "axios";
    
    const axiosClient = axios.create({
        baseURL: "http://127.0.0.1:8000/api",
    })
    
    axiosClient.interceptors.request.use((config)=>{
        const token = localStorage.getItem('ACCESS_TOKEN');
        config.headers = {
            'Authorization': `Bearer ${token}`,
            'Access-Control-Allow-Origin': '*'
        }
        return config;
    })
    
    axiosClient.interceptors.response.use((response)=>{
        return response;
    },(error)=>{
        const {response} = error;
        if(response && response.status == 401){
            localStorage.removeItem('ACCESS_TOKEN');
        }
    
        throw error;
    })
    
    export default axiosClient;

我知道我有很多设置,使我的网站不安全,但这只是为了发展的目的。请帮助我已经挣扎了三天了><
这是我得到的结果(抱歉堆栈不想让我上传图像,因为格式化)

![1]: https://pasteboard.co/feqZ6JrGrvBM.png
![2]: https://pasteboard.co/nluAk8scYXzY.png
![3]: https://pasteboard.co/JF7yiHhH4XtB.png
acruukt9

acruukt91#

最终将整个项目从/var/www文件夹中移出,并仅为每个站点的公共文件夹创建符号链接。此外,在<VirtualHost>中,设置文档根路径与<Directory>路径相同。之后,laravel项目的默认CORS处理程序开始正常工作。

相关问题