Options request before Post Requests - ajax

Can anyone please explain in detail that why ajax uses OPTIONS request before POST request while using headers in APIs.
Is there any way to bypass the OPTIONS request, I just want POST request on my server.
Thanks in advance :)

Consider using Axios
https://www.npmjs.com/package/axios
axios.get( url,
{ headers: {"Content-Type": "application/json"} } ).then( res => {
if(res.data.error) {
} else {
doAnything( res.data )
}
}).catch(function (error) {
doAnythingError(error)
});

Related

How to override cy.request() and set up bearer authorization header globally?

I need to set the authorization bearer header for cy.request() globally to avoid setting it up multiple times.
Here I found some potential way to do it.
So in my support/commands.ts I have:
Cypress.Commands.overwrite('request', (originalFn, ...options) => {
const optionsObject = options[0];
if (optionsObject === Object(optionsObject)) {
optionsObject.headers = {
authorization: `Bearer ${Cypress.env('authorizationToken')}`,
...optionsObject.headers,
};
return originalFn(optionsObject);
}
return originalFn(...options);
});
And in the test I have:
cy.request({
method: 'POST',
url: '/someEndpoint',
body: someBody
}).then(response => {
expect(response.status).eq(200);
return response.body;
});
And unfortunately, I get 401: Unauthorized error and it looks like the authorization bearer token was not added to headers:
What do I do wrong here? I use Cypress v 10.10.0

Laravel The GET method is not supported for this route

I have laravel-vue application and one of my functions is running on post request but strange is that I get GET request error:
The GET method is not supported for this route. Supported methods: POST.
code
Route
Route::post('distanceCost', 'Api\Front\CartController#distanceCost');
Component
sendShippingRequest() {
// post request
axios.post('/api/distanceCost/', this.form, {
headers: {
Authorization: 'Bearer ' + localStorage.getItem('access_token')
}
})
.then(response => {
//....
})
.catch((error) => {
console.log('error', error);
});
}
Any idea?
The problem is, that in response to a POST to /api/distanceCost/, Laravel will respond with a redirect to /api/distanceCost. Your browser will then send a request to /api/distanceCost, but this time, it will use GET and it will not send the post payload. This is why your server replies with an error code.

Adding multiple headers to graphql client (apollo-boost)

const client = new ApolloClient({
uri,
onError: (e: any) => {
console.log('error: ', e); // Failed to fetch
console.log(e.operation.getContext()); // it does show it has x-abc-id
},
request: operation => {
const headers: { [x: string]: string } = {};
const accessToken = AuthService.getUser()?.accessToken;
const activeClientId = UserService.getActiveClientId();
headers['x-abc-id'] = activeClientId;
if (accessToken) headers['Authorization'] = `Bearer ${accessToken}`;
operation.setContext({ headers });
}
});
The problem here is when i just add Authorization header it makes the POST call and shows the expected error.
But when i add x-abc-id header which is also expected by backend it only makes OPTIONS call (no post call)
P.S. On postman adding both headers works completely fine.
Found what the issue was, thought to share if it help.
Postman does not perform OPTIONS call before sending request to backend.
In OPTIONS call, 👇represents what client call contains: [authorization, content-type, x-abc-id]
BUT what does server expects: 👇
Just authorization, content-type
So it's a calls headers mismatch (nothing related to Apollo).
x-abc-id header explicitly has to be allowed in CORS configuration on backend.
Thanks to Pooria Atarzadeh

How to set authorization header in vue.js

I'm making an axios post call with the JWT token generated after successful login. For all the requests I need to attach JWT token in header and in the back-end which is developed on spring -boot I have logic to get the token from header and validate it.
From the browser, first the OPTIONS request goes to back-end where it gives me 403 error and in the back-end If I sysout headers, I can't find the header name X-XSRF-TOKEN
axios.post("http://localhost:8004/api/v1/auth", { "username": "test", "password" : "test"})
.then((response) => {
let token = response.data.token;
axios.defaults.headers.common["X-XSRF-TOKEN"] = token;
axios.post("http://localhost:8004/api/v1/getdata", {"action" : "dashboard"})
.then((response) => {
console.log(response.data);
}, (error) => {
console.log(error);
})
}, (error) => {
console.log(error);
})
Spring boot part
#Controller
#CrossOrigin(origins = "*", allowedHeaders = "*")
#RequestMapping(path = "/api/v1")
public class ApplicationController {
#PostMapping(path = "/getdata")
#ResponseBody
public SessionData getData(#RequestBody ProfileRequest profileRequest) {
try {
return profileService.getData(profileRequest);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
Setting Authorization Header is not something to do with vue, but it
is something to do with axios.
axios.post("http://localhost:8004/api/v1/getdata", {"action" : "dashboard"}, {
headers: {
Authorization: 'Bearer ' + token,
}
})
When you get the auth token you can configure the axios instance with:
axios.defaults.headers.common['Authorization'] = `Bearer ${token}`
common means applying the header to every subsequent request, while you can also use other HTTP verb names if you want to apply a header to only one request type:
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'
You will find more info in https://github.com/axios/axios#config-defaults
...
axios.post('http://localhost:8004/api/v1/auth',
{ "username": "test", "password" : "test"}, {headers: { X-XSRF-TOKEN: `${token}`}})
...
the issue might not be axios but the cors policy set by spring security.
If you are using spring security check out this answer
I had the same issue, that answer helped solve my problem.

Response headers in Angular interceptor

I have an interceptor for authentication.
I want to get a header out of the response when I get a 401 response error.
Interceptor is:
function ($httpProvider, fileUploadProvider) {
$httpProvider.interceptors.push(function($q, $localStorage) {
return {
'request': function(config) {
if ($localStorage.token) {
config.headers.Authorization = 'Bearer ' + $localStorage.token;
}
return config;
},
'responseError': function(response) {
if (response.status === 401) {
//$rootScope.$broadcast('unauthorized');
// WWW-Authenticate: Bearer error="invalid_token"
var authResult = response.headers('WWW-Authenticate');
if (authResult.indexOf("invalid_token")>-1) {
$localStorage.token = null;
$timeout(function(){
;
});
}
}
return response;
}
};
I want to get the WWW-Authenticate header from the response.
I can confirm the header is in the response of the web service call by looking at the network tab in Chrome developers tools. If I set a break point in the response handler function and then run console.log(response.headers()) in the console I get:
Object {}
undefined
How do I get to the response headers?
The responseError function receives rejection instead of response.
Therefore if you want to access response headers, what you need is like below.
'responseError': function(rejection) {
if (rejection.status === 401) {
console.log(rejection.config.headers);
}
}
I hope this would help you. :)
Although I know this is not answer and should post as comment, I post it here to use screen capture image.
I tried to get a response header with my test enviroment like below.
nodejs server
res.setHeader('WWW-Authenticate', 'invalid_token');
res.status(401).send();
angularjs
'responseError': function(rejection) {
if (rejection.status === 401) {
console.log(rejection.headers('WWW-Authenticate'));
}
}
Chrome dev tool screen capture
As you can see, I could get the response header correctly.
Therefore I think that there seems to be some problem in your server code where you set a response header.
Would you like to show us your chrome dev tool screen capture and your server code where you set the response header?

Resources