What works
I have a simple word game I've built. It works great. One thing users have requested is a word validity check. I am running the oxford dictionary api on an AWS Lambda Proxy/Node.js end-point, which works great when I access the APIGateway uri via the browser.
I chose an AWS Lambda function in order to protect my Oxford API key, and have more direct CORS control.
Steps taken
I have enabled CORS in the AWS APIGateway, and using a "*" wildcard during development.
I started to code the addition to the game, using my local server, # 127.0.0.1.
Error encountered
I have run into the following issue:
myproject.html:57 Cross-Origin Read Blocking (CORB) blocked cross-origin response https://XXXXXXXXXXX.execute-api.us-east-2.amazonaws.com/prod/dictionary?word=help with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
getWord # myproject.html:57
(anonymous) # myproject.html:67
The client code
I am using a simple fetch:
var base_url = "https://XXXXXXXXXXX.execute-api.us-east-2.amazonaws.com/prod/dictionary?word=";
getWord = function(word){
fetch(base_url+word, {
headers: {
'content-type': 'application/json'
},
method: 'GET',
mode: 'cors'
}).then(function(response) {
console.log(response);
});
}
The question
I have never heard of CORB. I don't understand what is triggering CORB, and what the steps are to resolve this. How are CORB issues resolved?
I just needed to persevere apparently. Just in case anyone ever runs into this:
Despite APIGateway CORS enablement, CORS authority is passed to the lambda function with Lambda proxy integration enabled. Although the initial URI request was accepted at the APIgateway, it ultimately failed due to lack of headers in the lambda response. Somehow This triggered CORB instead of CORS. I don't know why.
The answer is to ensure CORS is enabled in the APIgateway and that the lambda function response callback pattern contains a "Access-Control-Allow-Origin" header.
I had similar issue. I suggest using POSTMAN for debugging it as it shows headers and allows you to tweak whatever is needed in your request.
In my case I had to re-deploy my API after adding the header.
Attaching screenshot in case it might be of help to some users:
Integration response:
Method response:
Postman's headers response - working:
Related
I’m trying to POST an item in VS Code to my DynamoDB table via axios. I’m able to POST an item successfully via Postman, however when I try to POST an item with axios I get a 404 response error (below).
I’m wondering if I’m missing something when trying to POST an item via axios (below).
axios({
'method': 'post',
'url': 'https://na9blqj5y5.execute-api.us-east-1.amazonaws.com/test',
'Content-Type': 'application/json',
'data': {
'body': eraseThis,
}
})
.then((response) => {
return console.log('axiosResp', response);
})
.catch((err) => console.error('axios', err))
One thought that I had is that I should be importing the AWS SDK and invoke my lambda function with my credentials from that (below)? Any help would be greatly appreciated!
This is a successful POST request in Postman.
Now I'm getting a CORS error I had a few weeks ago (even after enabling CORS on the API resource in the API Gateway interface).
Below is the updated code using the aws-sdk
Your examples are hard to follow because they don't match.
first screenshot url is a different api gateway endpoint address than the postman screenshot
first uses the /test stage and the 2nd uses a /prod/customer
So right off I'm wondering if you just have different code deployed to different stages? Assuming you've ruled that out though and that's not the case I think what you mean to say is that your axios call made via browser fails whereas postman works.
That's actually expected behavior because postman isn't a browser and bypasses the CORS restrictions that browsers implement. There are plenty of existing questions here that explain that so I'm not going into that further.
I believe the fix for this is to update your lambda handler (the actual lambda proxy that returns a response) to always return a Access-Control-Allow-Origin header as documented by AWS here. To allow all origins you can use a wildcard *. ex:
headers: {
"Access-Control-Allow-Headers" : "Content-Type",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS,POST,GET"
}
Make sure you understand the implications of using *, which is a discussion for a different post.
Not sure what I did, but the call to dynamodb randomly started working. I think I had a syntax error, or something..
I'm troubleshooting a CORS issue and am currently analyzing the preflight headers.
I'm using an "HTTP" API in aws apigateway (different from what apigateway calls a "REST" api) to connect to a lambda function using the "lambda function" apigateway integration type.
It seems that no matter what I set in the CORS menu for HTTP apis, the preflight Response just doesn't have the headers I think I've enabled.
In the image below from devtools network tab, it's clear that apigateway is responding (hence the apigw-requestid). However, I would expect the Access-Control-Allow-Origin header to be returned too. No such luck.
My $default stage is set to autodeploy.
I have a proper route and integration attached to the lambda, along with the proper http verb (POST in my case).
There's no authorization set.
I've tried returning the proper headers in my lambda itself, but as the aws documentation says, apigateway ignores them and writes its own stuff. (the lambda wasn't even contacted unless I added an OPTIONS route .. which seems unnecessary anyway)
Yes, there are many such questions here, but most direct you to apigateway "REST" apis, not "HTTP."
I have also encountered this problem. I was using Axios and a GET request was working fine, but a PUT request was giving me a CORS error. I had configured CORS in the API Gateway exactly the same as you. Postman was working fine for PUT and GET.
I added the below to my lambda headers and added a route in API Gateway.
headers = {
"Content-Type": "application/json",
"Access-Control-Allow-Origin": "*",
"Access-Control-Allow-Methods": "OPTIONS, GET, PUT",
"Access-Control-Allow-Headers": "*"
};
Note that Access-Control-Allow-Methods could not be a * for Safari as it's not supported: Access Control Allow Methods.
I'm trying to call Github REST API from client-side javascript (in browser).
My code does the following (I'm trying to get a zip containing the branch mkdocs_page of a private repository) :
const endpoint = 'https://api.github.com';
const resource = '/repos/astariul/private-gh-pages/zipball/mkdocs_page';
const options = {
mode: 'cors',
headers: {
'Authorization': 'Basic ' + btoa(`${pat}`), // pat contains my Personal Access Token
}
}
return fetch(`${endpoint}${resource}`, options);
But it does not work :
The preflight request fails with 404.
The console error message :
Access to fetch at 'https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page' from origin 'null' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status.
In the process of debugging this, I tried to reproduce the problem with curl. And when I specify an authenticated request, it works :
curl --user "<my_PAT_token>" -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 204 No Content
But if the request is not authenticated, it does not work :
curl -i https://api.github.com/repos/astariul/private-gh-pages/zipball/mkdocs_page -X OPTIONS
HTTP/1.1 404 Not Found
Note : it works fine when I'm trying to get the master branch (authenticated or not). However it fails after, when being redirected :
Access to fetch at 'https://codeload.github.com/astariul/private-gh-pages/legacy.zip/refs/heads/main?token=XXX' (redirected from 'https://api.github.com/repos/astariul/private-gh-pages/zipball') from origin 'null' 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.
Is it a bug in the Github API ? Or I'm doing something wrong ?
There’s no way to force authentication in a preflight request. The preflight is controlled totally by the browser, and nothing about it is exposed in any way that you can manipulate from frontend JavaScript code. And the requirements for the CORS protocol explicitly prohibit browsers from including any credentials in preflight requests.
For a detailed explanation, see the answer at https://stackoverflow.com/a/45406085/.
Since the preflight involves the browser making an OPTIONS request, then in general, if a server requires authentication for OPTIONS request to a particular resource (which seems to be the case for the GitHub URL cited in the question) that’s not at all necessarily an unintended bug.
That’s because the only normal case in which a preflight is performed and an OPTIONS request is sent is for the case of frontend JavaScript code running in a browser. Requests made from server-side code or from code running in shell/command-line environment or from desktop apps or native mobile apps don’t involve sending an OPTIONS request.
So, lack of support for unauthenticated OPTIONS requests to a particular resource would only be a bug if the provider actually intended it to be used from frontend code running in a browser. In other words, it can instead indicate the provider intentionally doesn’t want it to be used from frontend JavaScript code (which seems to be the case for the URL cited in the question).
I am trying to integrate Yammer API in my Vue.JS project, for Http calls I am using Vue-Resource plugin. While making GET Http call to get posts from Yammer it gives me following error -
Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource.
I tried postman tool and that gives successful response, but when I try to run the same thing in my Vue.JS project using Vue-Resource plugin it wont work.
The Vue.JS code snippet -
function(){
this.$http.get("https://www.yammer.com/api/v1/messages/my_feed.json").then((data)=>{
console.log(data);
});
In main.vue file i have -
Vue.http.interceptors.push((request, next) => {
request.headers.set('Authorization', 'Bearer my_yammer_token')
request.headers.set('Accept', '*/*')
next()
})
Then I tried the code snippets provided by Postman tool for jquery, that too not working.
jQuery code -
var settings = {
"url": "https://www.yammer.com/api/v1/messages/my_feed.json",
"method": "GET",
"timeout": 0,
"headers": {
"Authorization": "Bearer my_yammer_token",
"Cookie": "yamtrak_id=some_token; _session=some_token"
},
};
$.ajax(settings).done(function (response) {
console.log(response);
});
Though, I found similar questions but nothing worked for me.
I am working this to resolve from last 2 days but getting failed again and again. Please guide/help me.
A browser has higher security requirements than a request in PostMan. In a browser, you are only allowed to make XHR requests to your own current host (combination of domain + port) but not to other remote hosts. To nevertheless make a request to a remote host, you can use the browser built-in CORS. By using this, your browser makes a pre-flight request to the remote host to ask if the current page is allowed to request from that host. This is done via the Access-Control response headers. In your case, this header is probably missing or not allowing your page to access, which is why the request does not go through. Please read further into that topic.
However, in your case, using CORS probably won't be a solution for two reasons: To use CORS, the remote host must present a header which allows every requesting host (*) or your specific one. If you cannot set that setting anywhere on the remote host, it won't work. Second, it is not safe to place your authorization token into client-side JavaScript code. Everybody can just read your JS code and extract the authorization token. For that reason, you usually make the actual API call from the server-side and then pass the data to the client. You can use your own authentication/authorization against your server and then use the static authorization key on the server to request the data from the remote host. In that case, you'll never expose the authorization key to your user. Also, on the server-side, you do not have to deal with CORS as it works just like PostMan or curl as opposed to a browser.
I am currently developing a dashboard which consumes the Mention API. However, I am having difficulties due to the CORS policy.
If the dashboard is opened on Chrome or another browser that has a strict CORS policy, they make a preflight OPTIONS request each time, but these appear to not be supported by the Mention API.
Therefore, every time I do something like:
this.mentionAPI = axios.create({
baseURL: 'https://web.mention.net/api/accounts/my-account-id',
headers: {
'Authorization': 'Bearer my-access-token',
}
});
this.mentionAPI.get('/alerts')
.then((response) => {
console.log(response);
})
.catch((response) => {
console.log(response);
});
I get a response with the status 405 Method Not Allowed. This suggests that the OPTIONS requests are not handled by the Mention API at all.
Naturally, in my case I can just make sure that the browser is configured to not perform preflight requests. After all, my use case prescribes just one client, which I control completely. Alternatively, I could build a server-side service to make the requests on my behalf, however it seems like hunting a fly with cannon, since client side JavaScript is more than capable to perform everything else.
Any help on this issue would be really appreciated. Perhaps I'm misunderstanding how the API is intended to be consumed?