In laravel 5.8, / "vue": "^2.5.17" / "axios": "^0.18"
, I need to read external data which are read from postman ok :
https://imgur.com/a/SRBmK0P
I try to read these data using axios and got error:
https://imgur.com/a/o97xLm7
In the browse, I see details of the request :
https://imgur.com/a/EUkyV43
My JS code:
axios.post(window.REMOTE_SEARCH_WEB, {
"query": "pc gamers",
"blogger": false,
"company": false,
"influencer": false,
"article": false,
"pageId": 1,
"sort": null,
"sortOrder": null,
"searchType": 1,
"Access-Control-Allow-Origin": this.app_url,
"Access-Control-Allow-Methods": "POST",
"Access-Control-Max-Age": 86400,
"Access-Control-Allow-Headers": "Content-Type, Authorization",
'Access-Control-Allow-Credentials': 'true'
}).then((response) => {
where this.app_url
is home url
of the site the app run at.
Googling I found several parametersAccess-Control-*
must be filled, like in code above, but that did not help me.
Can you say how I to fix it?
Can it be that a decision could be from my js code with axios to run action in my control and from there to make request using PHP/Laravel? If yes, please provide example of such decision...
MODIFIED BLOCK :
I installed https://github.com/barryvdh/laravel-cors package and
1) in file I added line in app/Http/Kernel.php
protected $middleware = [
// ...
\Barryvdh\Cors\HandleCors::class,
];
I added in middleware group I that is is not ‘/api’ internal, but external request.
Is it correct?
2) I left file config/cors.php without changes :
return [
'supportsCredentials' => false,
'allowedOrigins' => ['*'],
'allowedOriginsPatterns' => [],
'allowedHeaders' => ['*'],
'allowedMethods' => ['*'],
'exposedHeaders' => [],
'maxAge' => 0,
];
3) In axios.post request I removed all Access-Control parameters
axios.post(window.REMOTE_SEARCH_WEB, {
"query": "pc gamers",
"blogger": false,
"company": false,
"influencer": false,
"article": false,
"pageId": 1,
"sort": null,
"sortOrder": null,
"searchType": 1,
}).then((response) => {
4) But the same error in request : https://imgur.com/a/wbgmrps
What is wrong ?
Thanks!
You can solve it with creating an interceptor middleware in your backend, that will attach the Access-control-allow
headers to the request.
Create a middleware cors
public function handle($request, Closure $next)
{
return $next($request)
->header('Access-Control-Allow-Origin', '*') //REPLACE STAR WITH YOUR URL
->header('Access-Control-Allow-Methods', 'GET, POST, PUT, PATCH, DELETE, OPTIONS')
->header('Access-Control-Allow-Headers', 'content-type, authorization, x-requested-with');
}
Then list the middleware in global middleware list in app/http/kernel.php
protected $middleware = [
...
\App\Http\Middleware\Cors::class
]
All the informations you found about headers for CORS communication are correct but must be set on the API server that you are consuming, not on the server you are calling from.
You tried to add those headers in your ajax call made and installed the laravel-cors package, however these are installed both on the calling server (one is client side with javascript, the other is server side on laravel).
Hoping you have control on the api server you are consuming with your laravel/vue app the first thing you should to is to add this headers on all your api responses:
header('Access-Control-Allow-Origin: <insert calling domain here>')
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS'); // Use only the methods you are using
In developement mode you could just use Access-Control-Allow-Origin: *
, however in a production environment is highly recommended to use the correct domain. You are allowed to use the wildcard for partial urls, however remember to specify the port if you are not using 80/443. (ex. Access-Control-Allow-Origin: *.mydomain.com:8080
.
This is not enough however, by default laravel includes the bootstrap.js library in his app.js, that causes the inclusion of the CSRF token header in all the ajax calls made with axios. Here is the part of the source code in resources\js\bootstrap.js responsible for this:
/**
* We'll load the axios HTTP library which allows us to easily issue requests
* to our Laravel back-end. This library automatically handles sending the
* CSRF token as a header based on the value of the "XSRF" token cookie.
*/
window.axios = require('axios');
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
/**
* Next we will register the CSRF Token as a common header with Axios so that
* all outgoing HTTP requests automatically have it attached. This is just
* a simple convenience so we don't have to attach every token manually.
*/
let token = document.head.querySelector('meta[name="csrf-token"]');
if (token) {
window.axios.defaults.headers.common['X-CSRF-TOKEN'] = token.content;
} else {
console.error('CSRF token not found: https://laravel.com/docs/csrf#csrf-x-csrf-token');
}
And here the header of an axios call I just made from laravel
As you can see there are 2 headers that must be specified on your api server to make CORS work. Here is the third setting you should add:
header('Access-Control-Allow-Headers: X-CSRF-TOKEN, X-Requested-With');
You may have more headers to set, just check your call and add all of them, if you forgot any of them it will be specified in the browser console. Be careful however to not use the wildcard * because it's not supported here.
If you don't have control on the API server then it becomes complicated.
If the api server already supports Access-Control-Allow-Origin:* then you can remove your X-CSRF-TOKEN and X-Requested-With headers from bootstrap.js, however be careful because these are used for internal api calls from vue to your laravel backend.
In alternative you could work with a proxy with the same domain of your laravel server or you could use your laravel server to make the api calls for you.