I am unable to enable CORS on any resources from AWS Api Gateway.
I used the "Enable Cors" button present on the web UI:
But attempting to use in development or production yields:
I'm using jQuery 2.2.4 and the method $.post.
What's going wrong?
UPDATE: test staging:
SUCCESS UPDATE:
AWS documentation can be quite large. What I failed to realize is that you must EXPORT a client generated SDK which has a global variable that generates methods based on the resources you provided. As such, I can FINALLY return a succesfull result when I use THIS code:
const apigClient = apigClientFactory.newClient();
apigClient.purchaseTokenPost({}, card, {})
.then(function(result){
console.log(result);
}).catch(function(result){
console.log(result);
});
I found that even for an 'unsecured' api call, i.e. one that your didn't secure with an API key (like I did to test something out), once I enabled cors it would only work if I created an API key and sent it in with the request - easy to do, may want to give it a try.
ADDL INFO:
Here is a sample jquery that worked for me after I enabled CORS on the endpoint:
function loadData() {
$.ajax({
type: "GET",
cache: false,
url: "https://k4t999edod.execute-api.us-east-1.amazonaws.com/prod/myapicall",
crossDomain: true,
dataType: "json",
headers: { 'x-api-key': 'xoeNNQ9475PCAgLtNP18cTv6YTWWB2JFfOe', 'X-Amz-Date': '1/1/2000', 'X-Amz-Security-Token': 'xoeNNQ9475PCAgLtNP18cTv6YTWWB2JFfOe' },
success: function (response) {
//do something here.
}
});
}
Note I included the API key in two places (I scrambled the real ones)
CORS seems to be setup correctly for your method. I tested with this tool:
http://client.cors-api.appspot.com/client (Enter your invoke URL, the POST dropdown, and you can confirm the success "onload" callback is triggered)
Can you try making your request with plain JavaScript to narrow down if it's an issue with jQuery? See: A CORS POST request works from plain javascript, but why not with jQuery?
Edit:
Found this on http://enable-cors.org/server_awsapigateway.html. Looks like the One-Click CORS button in API Gateway isn't compatible with jQuery:
Amazon API Gateway adds support for CORS enabling through a simple button in the API Gateway console. Unfortunately that button has a partial behavior, thus setting CORS correctly only for 200 answer (so not other HTTP status codes) and ignoring JQuery header support. The best solution considered so far is about avoding to use the CORS button and set configurations manually. This can be achieved in a couple of steps:...
(Final) Edit: This is a bug with API Gateway not applying header mappings when the integration returns an error response. This has been a known issue for quite a while: https://forums.aws.amazon.com/thread.jspa?threadID=220324&tstart=0
Related
I am trying to subscribe an email to a list on mailchimp, I followed the documentation first, made a request using "Postman" added what was needed and everything works just fine, so I tried to do it on my website and it didn't work
I tried to made a simple request with the same values I set on postman, but everytime I try to send the request the response says
XMLHttpRequest cannot load
https://us12.api.mailchimp.com/3.0/lists/xxxxxx/members. Response
to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'https://mywebsite.com' is therefore not allowed
access. The response had HTTP status code 501.
I tried to find a way to overcome this but it has been impossible
I searched on stackoverflow everybody says to use jsonp or add something to the ajax call or use a mailchimp ajax plugin nothing has worked
I tried diferent stackoverflow posts like this one
Mailchimp subscribe using jQuery AJAX?
but almost all of them say the same
I tried cache: false dataType:jsonp crossDomain: true xhrFields: {withCredentials: true}
Here it is my code, I am using Jquery
$.ajax({
type: "POST",
url: "https://usxx.api.mailchimp.com/3.0/lists/xxxxxxxx/members",
data: { "email_address":email#adress.com, "status":"subscribed"},
headers: {
"Authorization": "Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx==",
"Content-Type": "application/json"
},
success: function(data){
alert('Thanks for subscribing');
},
error: function(data){
alert('there was an error, try again later');
}
});
I also Thought on creating my own api and then make the call to mailchimp api but I might ran into the same problem
Do you have any suggestions?
Thanks in advance
As charliefl noted, this is a CORS issue. MailChimp doesn't support CORS, mostly because it would require you passing your API credentials to the user of the webpage, allowing them to takeover your entire account.
Your two options for MailChimp are to proxy your requests through a server or, for signing people up to your list, you can build a custom signup form that uses a much more restricted API. The caveat of this second method is that it forces all of your subscribes through MailChimp's double opt-in process.
I have a backbone marionette application that makes REST api calls.
In my model when i make a api call to login i get a session value back and see the cookie being set in the browser
immediately after when i make another call to get the user information that is logged in i receive a different session or cookie value and no user is found. CORS is enabled and options calls are being made.
When i hook up the api to my other applications that were build off non backbone libraries it works fine. Does anyone know how to solve this?
Here is my post
doLogin: function( data ){
this.fetch({
data: JSON.stringify(data),
type: 'POST',
contentType: 'application/json',
error:(function (e) {
alert('error');
})
});
},
It is not clear on this piece of code but looks like your calls are going to different domains (once you mentioned CORS).
If that is really the case, I am afraid session and cookie might be different because they are probably specific only to the domain that your 1st request (doLogin) reached but not the 2nd request (fetch). More info: Sharing cookies across different domains and different applications (classic ASP and ASP.NET)
Another thing to look is if your both servers REALLY support CORS because one part of the setup is client-side and another is server-side (headers). More info on: http://www.html5rocks.com/en/tutorials/cors/
I've been stuck on consuming a web service created in PHP, not sure what I'm doing wrong.. Ive created a fiddle example here : http://jsfiddle.net/e97AV/
I've tried various combinations of things but keep on getting 404 not found feedback, when I specify jsonp i get no error message, but in the web console i can see a 404 error.. in the browser when I visit the url it is returning valid json
My question is how would I know when to use jsonp or json? Also these service have been provided to me from an external source other than agreeing on json being returned how would I know if the problem is on my side or theirs?
heres the ajax code
baseUrl = "http://exclusivegetaways.co.za/api.php";
$.ajax({
type: "GET",
url: baseUrl,
data: {something : "something"},
//contentType: "application/json; charset=utf-8",
dataType: "json",
success: function (result) {
alert("works");
alert(result);
},
error: function (a,b,cc) {
alert(a+b+cc);
}
});
I've since been able to pull json data from the ajax error object?? like so:
baseUrl = "http://exclusivegetaways.co.za/api.php?something=something";
$.ajax({
type: "GET",
url: baseUrl,
dataType: "json",
success: function (res) {
alert("worked");
//alert(res);
},
error: function(jqxhr) {
try {
f = JSON.parse(jqxhr.responseText);
...valid json returned here
} catch(err) {alert(err);}
}
});
This is because of a security restriction that prevents Ajax from querying remote locations.
As a workaround to enable access to a remote location via Ajax, you could build a custom URL in your webApp (in PHP for instance) which queries the distant API and returns JSON.
Then, in your JavaScript, you call this URL (from your application) via Ajax.
First: Always look at your JavaScript error console.
XMLHttpRequest cannot load http://exclusivegetaways.co.za/api.php?location=provinces.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://fiddle.jshell.net' is therefore not allowed access.
See also Ways to circumvent the same-origin policy
I've tried various combinations of things but keep on getting 404 not found feedback, when I specify jsonp i get no error message, but in the web console i can see a 404 error. in the browser when I visit the url it is returning valid json
This suggests that:
They don't support JSONP
They look at the HTTP headers and 404 your request to block access from Ajax (this isn't a good way to do that, the error code is misleading)
My question is how would I know when to use jsonp or json?
Usually by reading the documentation for the server you are trying to use
Also these service have been provided to me from an external source other than agreeing on json being returned how would I know if the problem is on my side or theirs?
Usually by working with whatever support is provided by the API provider (i.e. start with their documentation, then fall back to whatever means they provide for communicating with a human).
Due to Same Origin Policy your ajax request is allowed only if:
domain name, application layer protocol, and (in most browsers) port
number of the HTML document running the script are the same
In your case the application layer protocol is different, that's why your script fails.
Possible solutions are:
JSONP, which has to be provided by the server
CORS, which is a more 'elegant' and clean solution, but is not yet fully supported by IE (IE7 doesn't support it, IE8 has some limitations)
Answer taken from this link
Dictionary.com provides absolutely no documentation on how to grab data from them. I'm trying to use jQuery's ajax requests, but those are not working.
They provide a URL through which I'm supposed to be able to use. I'll provide this below.
http://api-pub.dictionary.com/v001?vid=<VID>&type=random&site=dictionary
They also provide a key, which I assume that I place in the <VID> spot.
Could someone please tell me what I'm doing wrong with this? I'll provide the code I'm using below:
$("#btnGetData").click(function() {
$.ajax({
url: "http://api-pub.dictionary.com/",
type: "GET",
data: "v001?vid=<VID>&type=random&site=dictionary",
success: function() { alert("success") },
});
});
Could someone please tell me what I'm doing wrong?
You are not passing the data correctly. Also the request url is http://api-pub.dictionary.com/v001. Try this:
$("#btnGetData").click(function() {
$.ajax({
url: "http://api-pub.dictionary.com/v001",
type: "GET",
dataType: "jsonp", //For external apis
data: {"vid": <VID>,
"type":"random"
"site": "dictionary"},
success: function() {
alert("success") },
});
});
UPDATE: Maybe you're being blocked by the same origin policy as #thordarson note, in that case add:
dataType: "jsonp" to your ajax call.
Possibility 1
You don't have access to their API. According to their API page they're very selective about who they give access to their API.
We are selective about our API partners and approve use as well as
develop terms on a case-by-case basis. If you are interested in using
our API, please contact us directly [...].
Possibility 2
You're being blocked by the same origin policy. Browsers are generally very strict about requests made by JavaScript across different domains. This can be bypassed using Cross-origin resource sharing. This requires configuring the server you're requesting, so in this case it's not viable.
Your best bet would be to create a server-side script that requests the URL and then using AJAX to request the file.
Example in PHP, let's call this request_dictionary.php:
<?php
$vid = "Your API key";
$type = $_GET['type'];
$site = $_GET['dictionary'];
$request_url = "http://api-pub.dictionary.com/v001?vid=$vid&type=$type&site=$site";
echo file_get_contents($request_url);
?>
Note: You probably need to change this to fit your needs (error handling, 404s, caching etc.). This code is untested.
Then change your jQuery so that it requests your file.
$("#btnGetData").click(function() {
$.ajax({
url: "/request_dictionary.php",
type: "GET",
data: "type=random&site=dictionary",
success: function() { alert("success") },
});
});
Warning
Using an AJAX call without a proxy (as explained in possibility 2) will expose your API key. This is against Dictionary.com's API Terms of Service.
2.1 Dictionary.com will assign and deliver to your Customer Application an Application Key to access the API. All Calls must
contain such Application Key. The Application Key is uniquely
associated with each Customer Application and all versions, upgrades
and updates thereof. The Application Key is Confidential Information
as defined in these Terms and Conditions. You must maintain and keep
the Application Key in a secure, embedded manner not accessible by any
third party. The Application Key is fully revocable by Dictionary.com
at any time. Dictionary.com may block attempts to access the API with
an invalid or revoked Application Key.
I've updated the code in possibility 2 to conceal the API key by keeping it in the PHP file.
Update/Note: Simply passing dataType: 'jsonp' to enable cross-origin calls is not enough. The responding server needs to respond with an Access-Control-Allow-Origin header containing your domain (or a rule that includes your domain). Any configuration of this kind is out of your hand as the requester.
Update/Note 2: Upon investigating the returned headers from your request URL, I can see no evidence of Access-Control-Allow-Origin. This means that even if you had access to their API, you wouldn't be able to access it using AJAX. Full headers below:
GET /v001?vid=%3CVID%3E&type=random&site=dictionary HTTP/1.1[CRLF]
Host: api-pub.dictionary.com[CRLF]
Connection: close[CRLF]
User-Agent: Web-sniffer/1.0.44 (+http://web-sniffer.net/)[CRLF]
Accept-Encoding: gzip[CRLF]
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8[CRLF]
Accept-Language: en-US,en;q=0.8[CRLF]
Accept-Charset: ISO-8859-1,UTF-8;q=0.7,*;q=0.7[CRLF]
Cache-Control: no-cache[CRLF]
Referer: http://web-sniffer.net/[CRLF]
I'm trying to validate a feed, using the web service that is in this question.
But browser does not allow me to send a ajax GET request to another server. And there is a one second restriction per each request in that web service, so I can't mirror requests from my server.
This is my current jQuery code:
var reqUrl = "http://validator.w3.org/feed/check.cgi?url=" + encodeURIComponent(theUrl);
$.get(reqUrl, function(data) {
// do something
});
Isn't there any other way?
Ajax calls are not valid across different domains unless you use JSONP. JQuery-ajax-cross-domain is a similar question that may give you some insight. Also as noted by Luis in the comments, JSONP has to also be implemented on the domain that you are getting the data from.
Here is an example for jquery ajax(), but you may want to look into $.getJSON():
$.ajax({
url: 'http://yourUrl?callback=?',
dataType: 'jsonp',
success: processJSON
});
Another option is CORS (Cross Origin Resource Sharing), however, this requires that the other server to enable CORS which most likely will not happen in this case.
I searched google and found this. the third answer says that:
In computing, the same origin policy is an important security concept for a number of browser-side programming languages, such as JavaScript. The policy permits scripts running on pages originating from the same site to access each other's methods and properties with no specific restrictions, but prevents access to most methods and properties across pages on different sites.(source)
you'd better see the answers of this question.
I think you can't use JSONP because you haven't any access to W3C script.
Update (explanations)
I the question I linked to there is another way that I can explain it to you. if you set Access-Control-Allow-Origin header to * as the answer said you can send requests to another domains. and to use it easily in an MVC application you can see this solution. Good luck
Update2
to allow just http://validator.w3.org/ you just should set Access-Control-Allow-Origin to http://validator.w3.org/
for more details as answer said go here.
As said you can use JSONP but the endpoint must also implement it, And its only used if you are requesting json data from the call. It looks like you are retrieving html.
You can also implement a simple proxy in your domain that pulls the data from the external location and serves it to the ajax call. You can develop a simple proxy in php using for instance CURL.
Make sure you understand the implications of this security wise making sure for instance that you protect your proxy to only make calls to that external url (whitelisting).
Update: I just noticed you cannot use the proxy solution. And after following the link you have suggested I have came across CORS, which I didnt event know about. So apparentry you can set some headers when you are serving the pages in your domain that will instruct the browser that requests to some domains can be done.
Check this page for how to implement it:
http://enable-cors.org/
I have read that you might have to tweak it a bit to work with IE but it seems that all browsers are now implementing it.
I know this is an old question, but I myself have been trying to create AJAX requests to validator.w3.org as well, hit the exact same issues and stumbled on this SO question.
However, I did find a solution;
As people have already stated, the main problem here is that the server must issue valid CORS headers, i.e.
Access-Control-Allow-Origin: *
I used Fiddler to check the response headers from validator.w3.org and sure enough, the headers were not set. However, they also have another tool that does at validator.w3.org/nu/.
Here is an example: http://codepen.io/DDN-Shep/pen/ogdGgO/
$('form').on('submit', function(e) {
e.preventDefault();
var data = new FormData(this);
$.ajax({
url: 'http://validator.w3.org/nu/', // Trailing '/' is important or you get a 301 HTTP response status code
type: 'POST',
data: data,
processData: false, // Required for jQuery & FormData
contentType: false, // Set by FormData, required by the server
success: function(data, status, xhr) { /* TODO */ },
error: function(xhr, status, error) { /* TODO */ },
complete: function(xhr, status) { /* TODO */ }
});
});
If you are ever unsure whether or not a server allows CORS, you can use this very helpful online tool;
test-cors.org = http://client.cors-api.appspot.com/client