I want to upload an image to Amazon S3 while I'm on the LocalHost and the server gives me that error: "Access-Control-Allow-Origin"
Is there any solution for this error?
Note: I'm working with mvc 5 if that helps. I have removed the bucket name becuase it's too long.
Full Error: "XMLHttpRequest cannot load https://s3.amazonaws.com/747d522f-cf44-48e1-93e0-fa52d8ec29ed.jpg. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:50918' is therefore not allowed access. The response had HTTP status code 403."
Thank you :)
Related
A simple HTTP GET request.
When I put the URL into the browser bar, the results come back. (a small JSON object)
When I put the same url into Postman (https://www.postman.com/) I got the following 403 error back:
ERROR: The request could not be satisfied
403 ERROR
The request could not be satisfied.
Bad request.
We can't connect to the server for this app or website at this time. There might be too much traffic or a configuration error. Try again later, or contact the app or website owner.
If you provide content to customers through CloudFront, you can find steps to troubleshoot and help prevent this error by reviewing the CloudFront documentation.
Generated by cloudfront (CloudFront)
Request ID: xxxxxxxxxxxxxxxx
What is causing this and how can I use Postman on API Gateway in AWS?
As a further clue to the puzzle - when I change the request type of 'post' in postman, I get the expected response for an undefined resource: {"message":"Missing Authentication Token"}
I've created an API with C++ and the following library: https://github.com/yhirose/cpp-httplib
In the API I've added a header to responses for CORS:
svr.Post("/suggest", [&dr](const Request &req, Response &res){
res.set_header("Access-Control-Allow-Origin","(origin here)");
(origin here) is the origin of the server making the request.
On the browser side I've also enabled an extension to bypass CORS. But when trying to make an AJAX request to the API, I still get this error in my browser console:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https://192.168.1.10:10120/suggest. (Reason: CORS request did not succeed).
The AJAX request is done through a script written in the Tampermonkey extension to work on a specific website.
Do I need to modify headers on the server hosting the website? Have I done something wrong on the C++ side?
Also it might be important to mention that the code worked before. All I did was come back to it another day with a different local IP address (which i reprogrammed into the c++ API)
I tried it again to answer #sideshowbarker and it gave me a new error about self signed certificates. After adding the exception it worked.
For a while, I was simply storing the contents of my website in a s3 bucket and could access all pages via the full url just fine. I wanted to make my website more secure by adding an SSL so I created a CloudFront Distribution to point to my s3 bucket.
The site will load just fine, but if the user tries to refresh the page or if they try to access a page using the full url (i.e., www.example.com/home), they will receive an AccessDenied page.
I have a policy on my s3 bucket that restricts access to only the Origin Access Identity and index.html is set as my domain root object.
I am not understanding what I am missing.
To demo, feel free to visit my site.
You will notice how it redirects you to kurtking.me/home. To reproduce the error, try refreshing the page or access a page via full URL (i.e., kurtking.me/life)
Any help is much appreciated as I have been trying to wrap my head around this and search for answers for a few days now.
I have figured it out and wanted to post my solution in case anyone else runs into this issue.
The issue was due to Angular being a SPA (Single Page App) and me using an S3 bucket to store it. When you try to go to a specific page via url access, CloudFront will take (for example, /about) and go to your S3 bucket looking for that file. Because Angular is a SPA, that file doesn't technically exist in your S3 bucket. This is why I was getting the error.
What I needed to do to fix it
If you open your distribution in Cloudfront, you will see an 'Error Pages' tab. I had to add two 'Custom Error Responses' that handled 400 and 403. The details are the same for 400 and 403, so I only include a photo for 400. See below:
Basically, what is happening is you are telling Cloudfront that regardless of a 400 or 403 error, to redirect back to index.html, thus giving control to Angular to decide if it can go to the path or not. If you would like to serve the client a 400 or 403 error, you need to define these routes in Angular.
After setting up the two custom error responses, I deployed my cloudfront solutions and wallah, it worked!
I used the following article to help guide me to this solution.
The better way to solve this is to allow list bucket permission and add a 404 error custom rule for cloudfront to point to index.html. 403 errors are also returned by WAF, and will cause additional security headaches, if they are added for custom error handling to index.html. Hence, better to avoid getting 403 errors from S3 in the first place for angular apps.
If you have this problem using CDK you need to add this :
MyAmplifyApp.addCustomRule({
source: '</^[^.]+$|\.(?!(css|gif|ico|jpg|js|png|txt|svg|woff|ttf|map|json)$)([^.]+$)/>',
target: '/index.html',
status: amplify.RedirectStatus.REWRITE
});
The accepted answer seems to work but it does not seem like a good practice. Instead check if the cloudfront origin is set to S3 Bucket(in which the static files are) or the actual s3 url endpoint. It should be the s3 url endpoint and not the s3 bucket.
The url after endpoint should be the origin
Add a Cloudfront function to rewrite the requested uri to /index.html if it doesn't match a regex.
For example, if none of your SPA routes contain a "." (dot), you could do something like this:
function handler(event) {
var request = event.request
if (/^(?!.*\..*).*$/.test(request.uri)) {
request.uri = '/index.html'
}
return request
}
This gets around any kind of side effects you would get by redirecting 403 -> index.html. For example, if you use a WAF to restrict access by IP address, if you try to navigate to the website from a "bad IP", a 403 will be thrown, but with the previously suggested 403 -> index.html redirect, you'd still see index.html. With a cloudfront function, you wont.
For those who are trying to achieve this using terraform, you only need to add this to your CloudFront Configuration:
resource "aws_cloudfront_distribution" "cf" {
...
custom_error_response {
error_code = 403
response_code = 200
response_page_path = "/index.html"
}
...
}
Please check from the console which error are you getting. In my case I was getting a 403 forbidden error, and using the settings which are shown in the screenshot worked for me
Okay, I've been all over these interwebs looking for some insight to my issue; I've probably been through over 80 stack overflow threads RE api gateway and such, but none of them seem to help or speak close enough to my issue.
I'm new to API Gateway and cors, but lets see if i can articulate the issue that i am seeing:
Setting up a API gateway proxy to Kinesis firehose hydrating a redshift database. The proxy, firehose, and redshift gateway are up and working when called in isolation, but when called from one of our customer sites, we get an error as follows:
XMLHttpRequest cannot load [api_call_here]. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [origin_website_here] is therefore not allowed access. The response had HTTP status code 403.
Okay, so that strongly implies that CORS is needed, right? in the console on the resource, enable cors, deploy, new error:
XMLHttpRequest cannot load [api_call_here]. Request header field $cookies is not allowed by Access-Control-Allow-Headers in preflight response.
Ooooooooookay, from the new OPTIONS method added by the enable CORS feature, in integration response, allowed headers, under access control allowed headers add '$Cookies', deploy.
Now i get a new error, very similar to the first error:
XMLHttpRequest cannot load [api_call_here]. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin [origin_website_here] is therefore not allowed access. The response had HTTP status code 415.
Notice the first error had HTTP status code 403, and this third one has status code 415. This is where I'm having issues. If I go into the GET method acting as the proxy method, body mapping templates, I have "When there are no templates defined (recommended)" selected.
Now, I read that when API gateway fails to find a matching template it rejects with a 415 error, so I changed aforementioned option to "When no template matches the request Content-Type header". That made the error disappear, but the data is still not being persisted to redshift when called from the origin. Again, when I call the api directly from postman, insomnia or just a plain old address bar, the records are added nicely.
Opening up chrome and looking at the header i see that the cookie is coming across as text/html.
Regarding the template mapping up there, i have only defined a map for application/json; could that be part of the problem?
Also, the response header as viewed from chrome's console is as follows:
content-length:37
content-type:application/json
date:Wed, 19 Apr 2017 23:43:35 GMT
status:415
via:1.1 [blahblabbleblah].cloudfront.net (CloudFront)
x-amz-cf-id:[blahblabbleblah]
x-amzn-requestid:[blahblabbleblah]
x-cache:Error from cloudfront
I'm relatively new to this so i dont see how cloudfront fits in with this, especially give that it is complaining about media type while the console is complaining about no access-control-allow-origin header.
At any rate, any help as to how to resolve the third error would be most appreciated.
What is the content-type in your requests from the browser? If content-type header isn't specified in the request, then API Gateway assumes "application/json" by default.
Opening up chrome and looking at the header i see that the cookie is coming across as text/html.
I am not sure if you meant that "Content-type" header's value in the request is set to "text/html". If yes, that's the problem. You will either need a matching template, or you will need to pass through by default by choosing "When no template matches the request Content-Type header".
I have some issue with AWS API GW with SQS integration. Problem was that incorrect content type in mapping template, I wrote application/json but correct is application/x-www-form-urlencoded
The request body will never be passed through to the integration.
Requests with a Content-Type header that don't match any templates
will be rejected with a HTTP 415 response.
I am trying to access a web service using $.ajax and it shows the below error:
XMLHttpRequest cannot load http://IPAddress/Services.cfc. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. The response had HTTP status code 404.
When I try to use the same web service in any of the soap client it works fine.