Laravel API + React front-end request, Axios returns 404 - Access-Control-Allow-Origin
P粉492959599
2023-09-02 12:50:08
<p>I'm trying to make a POST request to the Laravel API from React. When I send the request in development mode, the request is successful, but when I deploy the API(:8000) and the frontend(:80) on Apache2, the request is blocked by the strict mode policy and the CORS error indicates that my request is missing access control - Allow-Origin and 404 in response. But Laravel and React pages can be accessed in the browser. To make requests, I use Axios.
And the website should have the same base URL <code>http://localhost</code>
I tried many solutions but none worked for me. </p>
<h1>Laravel 10.x Kernel</h1>
<p>I've seen many users suggesting making middleware that adds headers to the server response.Similar content is added by default in Laravel (<code>conf/cors.php</code>);
My file looks like this</p>
<pre class="brush:php;toolbar:false;">'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,</pre>
<p>It is registered in <code>Kernel.php</code> as follows</p>
<pre class="brush:php;toolbar:false;">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,</pre>
<p>This is what is in <code>api.php</code> when I use custom middleware</p>
<pre class="brush:php;toolbar:false;">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']);
});</pre>
<p>Even using custom middleware has no success</p>
<pre class="brush:php;toolbar:false;">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');
}
}</pre>
<h1>Add header in Apache Laravel VirtualHost file</h1>
<pre class="brush:php;toolbar:false;"><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></pre>
<p>React Apache VirtualHost files look very similar to Laravel files</p>
<p>I didn’t succeed:(</p>
<h1>.htaccess in Laravel/public</h1>
<pre class="brush:php;toolbar:false;"><IfModule mod_headers.c>
Header set Cross-Origin-Resource-Policy 'cross-origin'
Header set Access-Control-Allow-Origin "*"
</IfModule></pre>
<h1>Set API address as proxy</h1>
<p>In <code>package.json</code> I added this line</p>
<pre class="brush:php;toolbar:false;">"proxy": "http://localhost:8000",</pre>
<p>Also tried using the <code>http-proxy-middleware</code> package
and <code>setupProxy.js</code></p> in the react/src folder
<pre class="brush:php;toolbar:false;">const { createProxyMiddleware } = require('http-proxy-middleware');
module.exports = function(app) {
app.use(
'/api/*',
createProxyMiddleware({
target: 'http://localhost:8000',
changeOrigin: true,
})
);
};</pre>
<h1>axios client script</h1>
<pre class="brush:php;toolbar:false;">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;</pre>
<p>I know many of my settings make my site insecure, but this is for development purposes only.
Please help I have been struggling with this for three days><</p>
<p>This is the result I got (sorry stack doesn't want me to upload the image due to formatting issues)</p>
<pre class="brush:php;toolbar:false;">![1]: https://pasteboard.co/feqZ6JrGrvBM.png
![2]: https://pasteboard.co/nluAk8scYXzY.png
![3]: https://pasteboard.co/JF7yiHhH4XtB.png</pre></p>
Finally move the entire project out of the /var/www folder and create symlinks only to the public folders for each site. Also in
set the document root path to be the same as the
path. After that the Laravel project's default CORS handler starts working normally.