Laravel API + React 前端请求,Axios 返回 404 - Access-Control-Allow-Origin
P粉492959599
P粉492959599 2023-09-02 12:50:08
[React讨论组]

我正在尝试从 React 向 Laravel API 发出 POST 请求。当我在开发模式下发送请求时,请求成功,但当我在 Apache2 上部署 API(:8000) 和前端 (:80) 时,请求被严格模式策略阻止,并且 CORS 错误表明我的请求缺少访问控制- Allow-Origin 和 404 作为响应。但 Laravel 和 React 页面可以在浏览器中访问。为了发出请求,我使用 Axios。 并且网站应该具有相同的基本 URL http://localhost 我尝试了很多解决方案,但没有一个适合我。

Laravel 10.x 内核

我看到许多用户建议制作中间件,将标头添加到服务器响应中。 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,

这是我使用自定义中间件时 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 文件中添加标头

<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 文件非常相似

我没有成功:(

Laravel/public 中的 .htaccess

<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",

还尝试使用http-proxy-middleware包 和react/src文件夹中的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

P粉492959599
P粉492959599

全部回复(1)
P粉226413256

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

热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号