OPTIONS HTTP method instead of GET - spring-mvc

I am new to ember js using version 3. From a route I am using this line
this.get('store').findAll('users');
Instead of setting HTTP method GET, it is setting HTTP method OPTIONS.
Because of server is getting OPTIONS as HTTP method, server side i am getting error.
io.katharsis.errorhandling.exception.MethodNotFoundException: OPTIONS:
/users/
and in browser I am getting this error
Request header field Access-Control-Allow-Origin is not allowed by Access-Control-Allow-Headers in preflight response.
I am having the below code in application adapter and #CrossOrigin(origins="*") on Spring Rest API side.
import DS from 'ember-data';
export default DS.JSONAPIAdapter.extend({
init() {
this._super(...arguments);
this.set('headers', {
'Access-Control-Allow-Origin': '*'
});
},
host: 'http://localhost:8082',
namespace: 'spring-katharsis'
});
If the request contain HTTP method GET, I think it may solve the issue.
Please help on this.

Related

Get CORS request works but Put CORS request fails in AWS Lambda proxy integration (.net6)

I am building a collection of lambdas with proxy integration, using AWS Serverless (SAM).
I am trying my Lambdas from a frontend I have in Blazor WASM. When a GET request is issued, then I get my results on my browser without CORS issues.
But I cannot issue a PUT request without getting the dreaded:
Access to fetch at 'https://myapi.execute-api.eu-central-1.amazonaws.com/Prod/updatevictual?userId=georanto#gmail.com&victualId=da1b2daa-3a73-425e-812e-e2f164f54507' from origin 'https://localhost:7260' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
If I create a dedicated OPTIONS Lambda for the PUT related end-point (as suggested here) then it works. I cannot have an OPTIONS Lambda because I intend to add authentication and the OPTIONS lambda does not work with it.
According to this it should be enough to send the headers as a response. And in the case of GET it is!
To fill in my response headers(adjusting for .net6), I set my cors by attaching the headers at the returned request thus:
private static APIGatewayProxyResponse AllowCors(this APIGatewayProxyResponse response)
{
response.Headers ??= new Dictionary<string, string>();
response.Headers.Add("Access-Control-Allow-Headers",
"Content-Type, Authorization, X-Amz-Date, X-Api-Key, X-Amz-Security-Token");
response.Headers.Add("Access-Control-Allow-Methods", "*");
response.Headers.Add("Access-Control-Allow-Origin", "*");
response.Headers.Add("Access-Control-Allow-Credentials", "false");
return response;
}
I am also logging my responses in Cloudwatch and the put response after the postman request is thus:
2022-05-12T06:08:30.297Z ecffb8ac-0cd9-4626-be96-6260e7a76d47 info Responding with:[{
"statusCode": 201,
"headers": {
"Access-Control-Allow-Headers": "Content-Type, Authorization, X-Amz-Date, X-Api-Key, X-Amz-Security-Token",
"Access-Control-Allow-Methods": "*",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Credentials": "false"
},
"multiValueHeaders": null,
"body": null,
"isBase64Encoded": false}]
When I issue the request in Postman I see in the response's headers that the CORS headers are set the way they were supposed to:
So I don't think that this is a code issue.
I have also tried to put all the methods (i.e. response.Headers.Add("Access-Control-Allow-Methods", "OPTIONS, DELETE, GET, HEAD, PATCH, POST, PUT") but also didn't work.
Any other ideas what could that be?
I "think" I had the same issue but I'm not familiar with .net... in your cloudfront distribution configuration, be sure to have a caching behavior that allows for put/patch/etc. and configure in that behavior a cache policy that depends on your headers

NextJS - fetch() works only inside getServerSideProps()

My fetch() method for making api requests works only when inside getServerSideProps() method.
For example I have api call for fetching a customer cart (and it is inside getServerSideProps):
const res = await fetch(apiUrl, {
method: 'GET',
headers: {
'Authorization': 'Bearer ' + jwtToken
}
});
And it works fine, I get response from api with customer cart. But when I try to make that api call on a button click, and when I move that inside button click handle method, then I get firstly:
Access to fetch at '...' from origin 'http://localhost:3000' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
After that when I set mode to 'no-cors', then I get this:
GET ... net::ERR_ABORTED 400 (Bad Request)
So how it is possible that when inside getServerSideProps, there are no any CORS issues and everything is good, but when works on a button click then I get CORS issue and after that there is that other 'Bad request' problem.
Becuase by design browsers block the API request when the API response doesn't have Access-Control-Allow-Headers. But when you fetch the API inside getServerSideProps the the API request is made by Node.js server which doesn't check for Access-Control-Allow-Headers.
If you want to make this API request in browser then you can fix it by:
// If you can change the API code, here's an example to add the CORS headers in a netlify serverless function, this is the API response that I return from a serverless function
return {
statusCode: 200,
headers: {
/* Required for CORS support to work */
'Access-Control-Allow-Origin': '*', // you can add the domain names here or '*' will allow all domains
/* Required for cookies, authorization headers with HTTPS */
'Access-Control-Allow-Credentials': true
},
body: JSON.stringify({
message: 'Hello from netlify'
})
}
or If your API backend is in Node.js and Express.js you can use cors npm package
if you don't have the access to change the API then try writing a wrapper API (or you can say a proxy API) that will make the API request and send it's response to you.
or If you just want the API request to happen for once only (on page load like componentDidMount) you can use the getServerSideProps.
For more detailed explanation on how to fix CORS error read
How does Access-Control-Allow-Origin header work?

CORS Error with Google Firebase Functions even though I've set Access-Control-Allow-Origin on server

I'm getting the following error on the browser when I run my react app on localhost which sends a payload to a Google Firebase function:
Access to fetch at 'https://< myproject >.cloudfunctions.net/< myfunction >' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
My Google Firebase function has the following code:
exports.<myfunction> = functions.https.onRequest(async (req, res) => {
res.set('Access-Control-Allow-Origin', 'http://localhost:3000');
res.set('Access-Control-Allow-Headers', '*');
console.log(req.body);
res.end()
});
The error I get on my firebase functions console log is the following:
SyntaxError: Unexpected token # in JSON at position 0
at JSON.parse ()
at createStrictSyntaxError (/worker/node_modules/body-parser/lib/types/json.js:157:10)
at parse (/worker/node_modules/body-parser/lib/types/json.js:83:15)
at /worker/node_modules/body-parser/lib/read.js:121:18
at invokeCallback (/worker/node_modules/raw-body/index.js:224:16)
at done (/worker/node_modules/raw-body/index.js:213:7)
at IncomingMessage.onEnd (/worker/node_modules/raw-body/index.js:273:7)
at emitNone (events.js:111:20)
at IncomingMessage.emit (events.js:208:7)
at endReadableNT (_stream_readable.js:1064:12)
My Client side code which triggers the function is the following:
submit(name) {
fetch('https://< myproject >.cloudfunctions.net/< my function >', {method: 'POST', headers: {"Content-Type": "application/json",
},
body: 'mytoken'
}).then(result => {console.log(result)});
}
Also, everything was working fine just minutes and days earlier! It is as though this error started popping up out of nowhere.
Your fetch request is sending a Content-Type header of application/json but the body is 'mytoken' which is not valid JSON. Try sending something like {"token":"mytoken"} instead.
Edit: Additionally, since you are setting the Content-Type header you are likely triggering a CORS preflight OPTIONS request and may want to use the CORS middleware to handle it.
Edit 2: The source of the error was indeed the fact that a plain string was being sent instead of a JSON object (and a JSON object was necessary due to the fact that the content-type was set to application/json). There was, however, an additional bug afterwords in that the JSON payload needed to be stringify'd. Accordingly, the following code for "body" is what made everything run successfully:
body: JSON.stringify({token: 'mytoken'})

Vue-Request not sending Authorization Header

I'm using VueJS with vue-request for http requests. I'm trying to subscribe an user to a Mailchimp list but Mailchimp uses BasicAuth, so I'm doing as such:
scope.$http.post('https://us15.api.mailchimp.com/3.0/lists/listid/members',
{...mydata...}, {headers: {Authorization: 'Basic myencodedAPIkey'}})
But I get an error from the API: 401 Unauthorized - Your request did not include an API key.
So I check the Network log on Chrome and the Authorization is on my headers like this: **Access-Control-Request-Headers: authorization** but it should be like **Authorization: myencodedAPIkey**
On the Console the error appears as:
XMLHttpRequest cannot load
https://us15.api.mailchimp.com/3.0/lists/listid/members. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://127.0.0.1:8000' is therefore not allowed
access. The response had HTTP status code 401.
When I use Postman it works just fine as the header is correctly sent.
This problem seems to have been solved here with setting the header on every request
https://laracasts.com/discuss/channels/vue/how-to-solve-the-allow-control-allow-cross-in-the-vuejs-header-request-setting?page=2
and here through setting it once
Vue-Request not sending Authorization Header
You are getting CORS error, when you are trying to request from one host to another, and the 'another' part does not allow it to happen. To prevent this error you can use webpack proxy configuration, so this way you do not have cross origin request, but I don't know how you will deal with this in production environment if your api does not allow cross origin requests.
In a project I'm working on, our devServer configuration is as follow
proxy: {
'/api': {
target: 'http://localhost:8080/'
}
},
with this, any request happening on /api/any/url will be redirect to localhost:8080/api/any/url

AngularJS with CORS and custom headers

I am using Angular $HTTP to make a CORS request to a remote API service (SmartyStreets.com). I have set the defaults as is well-documented.
.config(['$httpProvider', function($httpProvider) {
$httpProvider.defaults.useXDomain = true;
delete $httpProvider.defaults.headers.common['X-Requested-With'];
}])
When I make a plain request with no custom headers everything works as expected.
// This works as expected
$http({method: 'get', url: $scope.addr.url, headers: {}})
However, I need to now set some additional custom headers. But setting the custom headers breaks the CORS request.
// this results in the browser 404 error:
// No 'Access-Control-Allow-Origin' header is present on the requested resource
$http({method: 'get', url: $scope.addr.url,
headers: {'x-standardize-only': 'true', 'x- include-invalid': 'true'}})
I've been trying to figure this out for a couple days now...stuck. Anyone know how to solve this problem?
Thank you!!
Your server needs to correctly respond to the OPTIONS request that the browser will make on your behalf to determine if the CORS request is valid. It needs to contain an Access-Control-Allow-Headers header with the right info in it. See: https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS#Preflighted_requests

Resources