Created
August 27, 2015 13:44
-
-
Save kirilkirkov/e134198d0493dd0bc69a to your computer and use it in GitHub Desktop.
CORS (Cross-Origin Resource Sharing) - Ajax Request to another domain
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<h2>CORS (Cross-Origin Resource Sharing)</h2> | |
<p>When you do a cross-origin request, the browser sends <code>Origin</code> header with the current domain value.</p> | |
<pre> | |
Origin: http://zinoui.com</pre> | |
<p>When the server receives the request, check whether the origin header is within the allowed list, and sends a response with <code>Access-Control-Allow-Origin</code></p> | |
<pre> | |
Access-Control-Allow-Origin: http://zinoui.com</pre> | |
<p>If you want to allow access for all, use a wildcard '*'</p> | |
<pre> | |
Access-Control-Allow-Origin: *</pre> | |
<p>Simple request<br /> | |
A simple cross-domain request is one that:</p> | |
<ul> | |
<li>Does not send custom headers (such as X-PINGOTHER, etc.)</li> | |
<li>Only uses GET, POST or HEAD request methods</li> | |
</ul> | |
<p>This is how the simple <strong>cross domain ajax request</strong> should looks like:</p> | |
<pre> | |
<script type="text/javascript"> | |
// Using jQuery | |
$.get("http://www.example.org/ajax.php").done(function (data) { | |
console.log(data); | |
}); | |
// Using XMLHttpRequest | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", "http://www.example.org/ajax.php", true); | |
xhr.onload = function () { | |
console.log(xhr.responseText); | |
}; | |
xhr.send(); | |
</script></pre> | |
<p>Preflighted requests<br /> | |
Setting custom headers to XHR triggers a preflight request. With simple words this mean that preflight request first send an HTTP request by the OPTIONS method to the resource on the remote domain, in order to ensure that the request is safe to send. According W3C for non same origin requests using the HTTP GET method a preflight request is made when headers other than <code>Accept</code> and <code>Accept-Language</code> are set.</p> | |
<pre> | |
<script type="text/javascript"> | |
// Using jQuery | |
$.ajax({ | |
type: "GET", | |
headers: {"X-My-Custom-Header": "some value"}, | |
url: "http://www.example.org/ajax.php" | |
}).done(function (data) { | |
console.log(data); | |
}); | |
// Using XMLHttpRequest | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", "http://www.example.org/ajax.php", true); | |
xhr.setRequestHeader("X-My-Custom-Header", "some value"); | |
xhr.onload = function () { | |
console.log(xhr.responseText); | |
}; | |
xhr.send(); | |
</script></pre> | |
<p>Request with credentials<br /> | |
By default, for non same origin request, browsers will not send credentials (such a HTTP Cookies, HTTP Authentication and client-side SSL certificates). A specific attribute has to be set on the XMLHttpRequest object when it is invoked.</p> | |
<pre> | |
<script type="text/javascript"> | |
// Using jQuery | |
$.ajax({ | |
xhrFields: { | |
withCredentials: true | |
}, | |
type: "GET", | |
url: "http://www.example.org/ajax.php" | |
}).done(function (data) { | |
console.log(data); | |
}); | |
// Using XMLHttpRequest | |
var xhr = new XMLHttpRequest(); | |
xhr.open("GET", "http://www.example.org/ajax.php", true); | |
xhr.withCredentials = true; | |
xhr.onload = function () { | |
console.log(xhr.responseText); | |
}; | |
xhr.send(); | |
</script></pre> | |
<p>The Response<br /> | |
Let's see how the server response should looks like</p> | |
<pre> | |
<?php | |
// http://www.example.org/ajax.php | |
if (!isset($_SERVER['HTTP_ORIGIN'])) { | |
// This is not cross-domain request | |
exit; | |
} | |
$wildcard = FALSE; // Set $wildcard to TRUE if you do not plan to check or limit the domains | |
$credentials = FALSE; // Set $credentials to TRUE if expects credential requests (Cookies, Authentication, SSL certificates) | |
$allowedOrigins = array('http://zinoui.com', 'http://jsfiddle.net'); | |
if (!in_array($_SERVER['HTTP_ORIGIN'], $allowedOrigins) && !$wildcard) { | |
// Origin is not allowed | |
exit; | |
} | |
$origin = $wildcard && !$credentials ? '*' : $_SERVER['HTTP_ORIGIN']; | |
header("Access-Control-Allow-Origin: " . $origin); | |
if ($credentials) { | |
header("Access-Control-Allow-Credentials: true"); | |
} | |
header("Access-Control-Allow-Methods: POST, GET, OPTIONS"); | |
header("Access-Control-Allow-Headers: Origin"); | |
header('P3P: CP="CAO PSA OUR"'); // Makes IE to support cookies | |
// Handling the Preflight | |
if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { | |
exit; | |
} | |
// Response | |
header("Content-Type: application/json; charset=utf-8"); | |
echo json_encode(array('status' => 'OK')); | |
?></pre> | |
<p>Few notes:</p> | |
<ul> | |
<li>A wildcard '*' cannot be used in the 'Access-Control-Allow-Origin' header when the credentials flag is <code>true</code>.</li> | |
<li>Gecko 11.0 (Firefox 11.0 / Thunderbird 11.0 / SeaMonkey 2.8) removed support for using the <code>withCredentials</code> attributes when performing synchronous requests.</li> | |
</ul> | |
<h3>Browser support</h3> | |
<p>Chrome 3+, Firefox 3.5+, IE 10+, Opera 12+, Safari 4+</p> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Interested website: http://enable-cors.org