I have this web application where the web services are hosted on Amazon API gateway & the client application is hosted on cloudefront site. The services are CORS enabled. For any error such as http 500, 401, 403 I am able to receive the http status from the jqxhr object using status property. But it seem that for http status 413 i am getting status 0 in the code.
I have also noticed that http status 413 can be received if the request is made with in the server. But only for cross domain ajax, the status 413 is received as status 0.
Is there any way to handle http status 413 for cross domain ajax request.
Just brevity, consider the following code block, for http status 500, 401 the error callback log's out 500 or 401. But for 413 it displays 0.
$.ajax({
url: 'URL to AWS API Gateway',
success: function(d){
console.log(d);
},
error: function(a){
console.log( a.status );
}
});
See the following http://jsfiddle.net/tqgv7z9c/1/ (note http not https)
$.ajax({
url: 'http://www.mocky.io/v2/57bb03fc100000460a585000',
error: function(a){
$('#code').text( a.status );
}
});
I set it up using http://www.mocky.io/ with the following setup:
413 Request Entity Too Large
CORS Headers
Access-Control-Allow-Origin: http://fiddle.jshell.net
Access-Control-Allow-Methods: GET
You can see the 413 code is correctly returned.
Without seeing more detail on the response you receive, I'd imagine the browser is taking a follow up action, I know this is a problem if a 304 Found response comes back with a Location header, this will cause a new request to occur and you won't be able to intercept before the browser continues. if this is what is happening for you, there is likely little you can do about it if you don't have the ability to modify the API itself.
Related
I can't execute the 'GET' request with the getTasks() function.
$(document).ready(function(){
getTasks();
});
const apiKey = 'xxxxxxx';
function getTasks(){
$.ajax({
type: 'GET',
url: 'https://api.mlab.com/api/1/databases/taskmanager/collections/tasks?apiKey='+apiKey,
contentType: 'application/json',
xhrFields: {
withCredentials: true
},
success: function(data){
console.log(data);
},
error: function(){
console.log('FAIL')
}
})
}
The error that I get is:
api.mlab.com/api/1/databases/taskmanager/collections/tasks?apiKey=xxxxxxx
Failed to load resource: the server responded with a status of 400
(Bad Request)
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 400.
I understand that Google-Chrome on Windows is CORS enabled, and will not (by default) allow communication with a different domain. I'm not sure what a preflight request is. Regardless, I tried to implement what I saw from Using CORS - HTML5 Rocks (from the CORS from jQuery section), but to no avail.
At a guess, the remote API simply does not respond to pre-flight requests for GET calls (because it shouldn't have to).
Your code is triggering a pre-flight request because it is non-simple. This is due to your adding a Content-type: application/json header. A request Content-type header is used to indicate the request payload format. As it is a GET, there is no payload.
Try this instead...
$.getJSON('https://api.mlab.com/api/1/databases/taskmanager/collections/tasks', {
apiKey: apiKey
}).done(function(data) {
console.log(data)
}).fail(function() {
console.log('FAIL')
})
CORS is there to protect you. If you want some more info on it, wikipedia has a good entry on it.
It appears the issue here is that you're trying to access your mongodb hosted by mlab directly from your web app. As you can see in your code, you're providing credentials/api keys to make that request.
My guess is that mlab's intent of not allowing CORS is to prevent you from doing this. You should never put your private API keys in html to be hosted on a web page, as it's easily accessible by reading source code. Then someone would have direct access to your mongodb.
Instead, you should create a server-side application (node, or... ** Whatever **) that exposes an api you control on the same domain (or a domain you give permission to via CORS).
As far as the "preflight" request, if you look in your chrome debugging tools, you should see an additional request go out with the "OPTIONS" method. This is the request that chrome (and most other http clients) send out first to a server hosted on a different domain. it's looking for the Access-Control-Allow-Origin header to find out whether it's allowed to make the request. Pretty interesting stuff if you ever have some time to dig into it.
$http.post(main+'/api/getcard/', $.param({number: $scope.searchcard}), {headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'} })
.then(function (response) {
if(response.data != 0)
{
$location.path('/redeem/'+response.data.id);
console.log(response.data);
}
});
When i use this code my chrome sends:
Request URL:http://cards.mporeda.pl/branch/api/getcard
Request Method:GET
Status Code:405 Method Not Allowed
But when i use the same code on laravel serve localhost:8000 i get:
Request URL:http://localhost:8000/branch/api/getcard/
Request Method:POST
Status Code:200 OK
I don't have any more $http configurations only this header option in request. I have no errors on console before this request, so i quess my code is ok. Is there any problem with my server or something?
The URL your code says to make the request to is:
main+'/api/getcard/'
The URL your request says you are using is:
Request URL:http://cards.mporeda.pl/branch/api/getcard
This is most likely caused by:
you making a POST request to the URL you are trying to make a POST request to
the server responding with a 301 or 302 status and a Location header that redirects to the same URL without the / on the end
the browser following the redirect and making a GET request
If you look back up your list of requests, you should see the POST request.
To resolve this, you need to look at the server side code which is issuing the redirect.
Any thoughts on why I'm getting a "Failed to load resource: the server responded with a status of 400 (Bad Request)" in the Javascript on my client? (client-id obscured, I have one for an Oauth2.0 app via registration Rdio site)
index.html:
<script src="https://www.rdio.com/api/api.js?client_id=12345678"></script>
response:
https://www.rdio.com/oauth2/authorize/auto?response_type=token&client_id=12345678&showSignup=true&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fhelper.html%3Fclient_id%3D12345678
Failed to load resource: the server responded with a status of 400 (Bad Request)
John
The response text from the https://www.rdio.com/oauth2/authorize/auto request should reveal the error. For example, making a request from the shell:
$ curl "https://www.rdio.com/oauth2/authorize/auto?response_type=token&client_id=12345678&showSignup=true&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2Fhelper.html%3Fclient_id%3D1234567"
For a valid client ID, a possible response might be:
Invalid redirect_uri
If this is the error you're receiving, which seems likely, to resolve it, you need to add your redirect_uri's domain to the Redirect URIs in your Rdio application's settings.
I'm attempting to do a simple GET request from a server hosting some account data. The request requires an Authorization header in order to function correctly. I have performed the GET request and retrieved the data successfully in Postman, but attempting to do so in Javascript via Ajax results in a "Invalid HTTP status code 405" error.
Below is a link to a fiddle and a screenshot of the Postman settings. Thanks.!
$.ajax({
beforeSend: function(xhrObj){
xhrObj.setRequestHeader("Authorization","Bearer tj7LTLycpQC6DRup5BkHUO7uVbYaAZI40");
},
type: "GET",
url: "https://api05.iq.questrade.com/v1/accounts",
success: function(e){
console.log(e)
}
});
http://jsfiddle.net/Ldjbp2j8/1/
POSTMAN SETTINGS
From Chrome's JS console:
Failed to load resource: the server responded with a status of 405 (Method Not Allowed)
Because you are adding an Authorization header, you have made the request complex. This requires the browser to make a preflight OPTIONS request to ask for permission to send the complex request.
The server you are making the request to is responding saying that OPTIONS requests are not allowed to that URL.
You will need to modify the server so that it responds appropriately to the preflight CORS request.
Postman doesn't need to make a preflight request because your browser trusts Postman's code. It doesn't know if it can trust the code it received from JSFiddle (AKA potential evil hacker site) with the data api05.iq.questrade.com (AKA potential online banking or company Intranet site) is willing to share with it.
Look at the console errors:
XMLHttpRequest cannot load https://api05.iq.questrade.com/v1/accounts.
No 'Access-Control-Allow-Origin' header is present on the requested resource.
Origin 'http://fiddle.jshell.net' is therefore not allowed access. The response had HTTP status code 405.
This is the CORS issue. Browsers sent OPTIONS aka pre-flight request to the server if the domain doesn't match with the domain of the running code.
And you must add the required headers to the responses as well.
You must modify server to handle that.
You can also use JSONP as an alternative.
I'm using an API that someone else in my company made, and one of the endpoints he's created accepts GET requests with an access key header provided from another endpoint. I use the following jQuery AJAX to call it:
$.ajax({
type:'GET',
url: 'http://myapi.com',
crossDomain: true,
headers: {
"token": data.AccessKey
}
})
In Chrome, this returns 2 error messages in the console:
OPTIONS http://myapi.com jquery.min.js:4k.cors.a.crossDomain.send jquery.min.js:4n.extend.ajax jquery.min.js:4(anonymous function) (index):69j jquery.min.js:2k.fireWith jquery.min.js:2x jquery.min.js:4(anonymous function) jquery.min.js:4
XMLHttpRequest cannot load http://myapi.com. Invalid HTTP status code 405 (index):1
In Firefox I get a different error:
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://myapi.com. This can be fixed by moving the resource to the same domain or enabling CORS.
But we enabled CORS on the API server (we were getting that message on Chrome, too, before we did) so I don't know why it's saying that.
I know that this endpoint is expecting a GET request. If I send this request with no headers at all, it returns a 200 status and a response containing the expected "You need a key to access this information". If we try it on hurl.it, the GET request with a valid key as a header returns the expected results.
Because of CORS, it's running the pre-flight OPTIONS request, which I think is what's giving the 405 error, but shouldn't the server accept OPTIONS methods? How do we ensure this method is accepted? Is there something else going on that I'm not catching? CORS is a new concept to me so feel free to ELI5 your answers.