To distinguish a CORS violation from other failed AJAX requests, you can check the response headers of the HEAD request using server-side code and submit the results to your client page. For example, if an AJAX request failed (status 0), you can call this script (call it cors.php ) and you probably know if the response headers contain Access-Control-* headers.
Examples:
cors.php URL = HTTP://ip.jsontest.com
cors.php URL = HTTP://www.google.com
cors.php URL = HTTP://10.0.0.1
returns
HTTP / 1.1 200 OK Access-Control-Allow-Origin: *
HTTP / 1.1 302 Found
Invalid request
cors.php - Customize if necessary
<?php /* cors.php */ $url = $_GET["url"]; if(isset($url)) { $headers = getHeaders($url); header("Access-Control-Allow-Origin: *"); if(count($headers) == 0) { die("Invalid request"); // cURL returns no headers on bad urls } else { echo $headers[0]; // echo the HTTP status code } // Include any CORS headers foreach($headers as $header) { if(strpos($header, "Access-Control") !== false) { echo " " . $header; } } } function getHeaders($url, $needle = false) { $headers = array(); $ch = curl_init($url); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 4); // Timeout in seconds curl_setopt($ch, CURLOPT_TIMEOUT, 4); // Timeout in seconds curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_VERBOSE, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD'); // HEAD request only curl_setopt($ch, CURLOPT_HEADER, true); curl_setopt($ch, CURLOPT_HEADERFUNCTION, function($curl, $header) use(&$headers) { array_push($headers, $header); return strlen($header); }); curl_exec($ch); return $headers; } /* Drakes, 2015 */
Client side wiring harness:
function testCORS(url, $elem) { $.ajax({ url: url, timeout: 4000 }) .fail(function(jqXHR, textStatus) { if(jqXHR.status === 0) { // Determine if this was a CORS violation or not $.ajax({ context: url, url: "http://myserver.com/cors.php?url=" + escape(this.url), }) .done(function(msg) { if(msg.indexOf("HTTP") < 0) { $elem.text(url + " - doesn't exist or timed out"); } else if(msg.indexOf("Access-Control-Allow-Origin") >= 0) { $elem.text(url + " - CORS violation because '" + msg + "'"); } else { $elem.text(url + " - no Access-Control-Allow-Origin header set"); } }); } else { // Some other failure (eg 404), but not CORS-related $elem.text(url + " - failed because '" + responseText + "'"); } }) .done(function(msg) { // Successful ajax request $elem.text(this.url + " - OK"); }); /* Drakes, 2015 */ }
Wiring harness driver:
// Create a div and append the results of the URL calls $div = $("<div>"); $("body").append($div); var urls = ["http://ip.jsontest.com", "http://google.com", "http://10.0.0.1"]; urls.map( function(url) { testCORS(url, $div.append("<h4>").children().last()); });
Results:
http://ip.jsontest.com - OK
http://google.com - no Access-Control-Allow-Origin header set
http://10.0.0.1 - does not exist or is not running