Reputation: 161
I have REST api on backend. I need to make ajax request to POST some data and I write:
$(function() {
$('#createPin').click(function(e) {
e.preventDefault();
var urlAjax = "http://www.agroagro.com/test/v1/register";
$.ajax({
type: "POST",
url: urlAjax,
contentType: "application/x-www-form-urlencoded",
data: {
name: "Mile3",
email: "[email protected]",
password: "face1book"
},
crossDomain:true,
success: function(data) { console.log(data); },
error: function(data) {console.log(data); },
dataType: 'json',
beforeSend: function (xhr) {
xhr.setRequestHeader("Access-Control-Allow-Origin", "*");
},
headers: {
'Access-Control-Allow-Origin': '*'
}
});
});
});
but on click I get:
OPTIONS http://www.agroagro.com/test/v1/register jquery-latest.min.js:4 sendjquery-latest.min.js:4 m.extend.ajaxtest.html:114 (anonymous function)jquery-latest.min.js:3 m.event.dispatchjquery-latest.min.js:3 r.handle
XMLHttpRequest cannot load http://www.agroagro.com/test/v1/register. Invalid HTTP status code 404
Object {readyState: 0, getResponseHeader: function, getAllResponseHeaders: function,
setRequestHeader: function, overrideMimeType: function…}
But when I try to run http://www.agroagro.com/test/v1/register on Chrome Advanced Rest Client extension
then all works fine... How and why? What is wrong with my ajax request?
See IMAGE: https://i.sstatic.net/XnZCX.png - as you can see all works great with that extension cross domain.
Upvotes: 0
Views: 11556
Reputation: 898
It is your backend API that needs to return the proper CORS header. In the easiest variant, just have the server reply to the preflight request (HTTP OPTIONS
verb) with this header:
Access-Control-Allow-Origin: *
When you already have this response header set up, please note that your question shows a 404
code (Not Found). When I browse to http://www.agroagro.com/test/v1/register, I am seeing a 404
, too. This may only be the case for GET
requests, though.
By setting the crossDomain
property to true
, you are telling jQuery to send a JSONP request. A JSONP request works by embedding a <script>
tag into the body, which triggers a GET
request.
When the server is equipped with the proper CORS headers, you should disable crossDomain
. Since, according to the jQuery documentation, crossDomain
defaults to true
if the target domain differs from the domain of the currently open web page, use this snippet:
$.ajax({ type: "POST", crossDomain: false, // ... });
For cross-domain requests, the browser sends a preflight request like this first:
OPTIONS /test/v1/register HTTP/1.1
Host: www.agroagro.com
Connection: keep-alive
Access-Control-Request-Method: POST
Origin: http://agroagro.com
User-Agent: Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/39.0.2171.62 Safari/537.36
Access-Control-Request-Headers: access-control-allow-origin, accept, x-requested-with, content-type
Accept: */*
Referer: http://agroagro.com/test.html
Accept-Encoding: gzip, deflate, sdch
Accept-Language: de-DE,de;q=0.8,en-US;q=0.6,en;q=0.4
To find out if the browser may send the POST request, the server response is checked for an Access-Control-Allow-Origin
header. However, when receiving the above request, the API server replies like this:
HTTP/1.1 200 OK
Date: Fri, 28 Nov 2014 10:37:18 GMT
Content-Type: text/plain
Content-Length: 0
Connection: keep-alive
Set-Cookie: __cfduid=d57edcdbd0a20a0d11df4dda7c3753d611417171038; expires=Sat, 28-Nov-15 10:37:18 GMT; path=/; domain=.agroagro.com; HttpOnly
Allow: POST,OPTIONS,GET,HEAD
Set-Cookie: PH_HPXY_CHECK=s1; path=/
Cache-control: private
Server: cloudflare-nginx
CF-RAY: 1905edebcdb50f69-FRA
As you can see, there is no Access-Control-Allow-Origin
header returned for the OPTIONS
request.
Solution: Have the API endpoint return the Access-Control-Allow-Origin
header not only for the POST
request, but rather for the preflight OPTIONS
request.
Upvotes: 2
Reputation: 6722
send the below headers from your server
Access-Control-Allow-Origin : THE SITE FROM WHICH YOU WILL MAKE THE AJAX REQUEST
Access-Control-Allow-Credentials : true
then in jquery add the below code
xhrFields: {withCredentials: true }
Upvotes: 0