I'm calling POST on a third-party API that I've been working with via jQuery's $.ajax function. However, when I make the call I get the following error: XMLHttpRequest cannot load http://the-url.com. The request was redirected to 'http://the-url.com/anotherlocation', which is disallowed for cross-origin requests that require preflight.
I saw from this post that this might be a Webkit bug, so I tried it in Firefox (I'm developing in Chrome) and I got the same result.I've tried this on Chrome and Firefox and I get the same result.
Per this post, I also tried using jsonp both by setting the crossDomain
property of the $.ajax function to true
and setting the dataType
to jsonp
. But, this caused a 500 internal server error.
When I start Chrome with the --disable-web-security flag, I don't have any problems. However, if I start the browser normally, then I get the error.
So, I guess this might sort of be a 2-part question. What can I do to make this cross-domain request? If JSONP is the answer, then how do I go about figuring out if the third-party API is set up correctly to support this?
EDIT: Here's the screenshot when I make the call with the browser security disabled: https://drive.google.com/file/d/0Bzo7loNBQcmjUjk5YWNWLXM2SVE/edit?usp=sharing
Here's the screenchost when I make the call with the browser security enabled (like normal): https://drive.google.com/file/d/0Bzo7loNBQcmjam5NQ3BKWUluRE0/edit?usp=sharing
To your first question,
What can I do to make this cross-domain request?
The following request headers are first sent to the server. Based on the response headers, the UserAgent, i.e. browser here, will discard the response(if any) and not give it back to the XHR callback, when the headers don't add up.
Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header
Your server should then respond with the following headers:
Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: X-Custom-Header
Example taken from - https://stackoverflow.com/a/8689332/1304559
You can use tools like Fiddler or Web Inspector Network tab(Chrome) or Firebug's network tab to find the headers the server is sending back in response to your request.
The third party API server url should respond back with the supported values. If it doesn't that's your problem.
Can't be of much help in JsonP 500 server error, as it says Internal Server Error
UPDATE
I saw your screen shots, couple of things to notice here
HTTP POST
is usedAccess-Control
headers found in both modes response. With second status code as 302
Origin
request header is null
, so I believe the HTML file is opened from the file system rather than from a web siteEnabling JSONP
Coming to the point of why JSONP is not working, reason - The web service config(of the ASMX specified), has not enabled GET
mode for the request. JSONP doesn't work with POST
.
Why 200
with security disabled?
The POST request is directly called with no OPTIONS
or preflight request fired before it, so server simply responds back.
Why 302
status code with security enabled?
First a little on how it happens when security flag is not disabled(default). The OPTIONS
request is fired to the URL. The URL should respond back with a list of HTTP methods that can be used, i.e. GET
, POST
, etc. The status code of this OPTIONS
request should be 200
.
In the current case, there is a redirect called when doing this. And the redirect is pointing to a custom error handler for a HTTP Server Error. I believe it is 404
error, which is being caught and redirected.[This could be because the custom handler is set to ResponseRedirect
instead of ResponseRewrite
] The reason for the 404
is cross-domain access is not enabled.
In case the custom error handling was turned off, this would have returned HTTP 500
code. I believe the problem can be found by checking the server logs immediately after firing a cross-domain request. It will be good to check the server logs for errors other than this, if any.
Possible solution
To enable access, there are two ways - detailed here. Or directly add the access control headers to web.config
file's customheaders
section.
When cross-domain access is enabled, the server should respond back to OPTIONS and allow the request to go through. This should return HTTP 200
unless there are other errors. But ajax callback will not be able to access the response. This can be done now only if Access-Control-Allow-Origin
is set to "*" or the Origin
request header value, and the Access-Control
as needed. And the ajax callback will receive the response as intended.
The third point, null Origin
. This will be a problem if the Origin
request header value is sent back as Access-Control-Allow-Origin
. But I am assuming you will be moving your HTML page to a web server, so that shouldn't be a problem.
Hope this helps!