cors兼容性解决

匿名 (未验证) 提交于 2019-12-03 00:18:01

很多人以为(包括我之前也是)只需要后端Apach返回的标头中Header set Access-Control-Allow-Origin: *”,就可以放心的使用,今天再跟大家说一次,这个CORS(跨域资源共享)的方案在POST下并不兼容IE7及以下,IE8-IE9则需要使用window.XDomainRequest.来兼容。

比较常用的跨域有jsonp和cors,本文将围绕这两个点来展开。

使用JSONP

虽然jsonp可以支持跨域ajax请求,但是jsonp只支持GET的方式,并不支持post方式,当使用表单发送数据或者数据量较大和安全性较高要求的情况下,你就只能使用post方式了。

$.ajax({     url : "http://top.caibaojian.com/cross-domain-cors/jsonp.php",     dataType:"jsonp", });   function mycallback(data) {     alert("Here: "+data.name); }

jsonp.php

mycallback({"name":"Ravishanker","age":32,"location":"India"})

如果要自动处理函数,可以使用下面的方法。在这种情况下,你不需要有任何额外的功能。您可以在成功回调中获得服务器响应。

$.ajax({ 	url : "http://top.caibaojian.com/cross-domain-cors/jsonp.php", 	dataType:"jsonp", 	jsonp:"mycallback", 	success:function(data) 	{ 		alert("Name:"+data.name+"nage:"+data.age+"nlocation:"+data.location); 	} });
<?php     $callback ='mycallback';       if(isset($_GET['mycallback']))     {         $callback = $_GET['mycallback'];     }        $arr =array();     $arr['name']="Ravishanker";     $arr['age']=32;      $arr['location']="India";          echo $callback.'(' . json_encode($arr) . ')';   ?>

使用CORS

设置标头

// PHP header("Access-Control-Allow-Origin: *");  // Apache (.htaccess) Header set Access-Control-Allow-Origin "*"

预处理

function createCORSRequest(method, url) {   var xhr = new XMLHttpRequest();   if ("withCredentials" in xhr) {      // "withCredentials"属性是XMLHTTPRequest2中独有的     xhr.open(method, url, true);    } else if (typeof XDomainRequest != "undefined") {      // 检测是否XDomainRequest可用     xhr = new XDomainRequest();     xhr.open(method, url);    } else {      // 看起来CORS根本不被支持     xhr = null;    }   return xhr; }  var xhr = createCORSRequest('GET', url); if (!xhr) {   throw new Error('CORS not supported'); }

绝大多数情况下,我们只需要和onloadonerror打交道,就像下面这样:

xhr.onload = function() {  var responseText = xhr.responseText;  console.log(responseText);  // 继续其它代码 };  xhr.onerror = function() {   console.log('There was an error!'); };

简单请求

  1. 不发送自定义header(如x-pingother,等)
  2. 只使用GET、POST或header的方法
//code from http://caibaojian.com/cors-post.html <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>

widthCredentials

默认情况下,非同一来源的请求,浏览器不会发送凭据(如HTTP cookies,HTTP认证和客户端的SSL证书)。如果有需要则需要在设置XMLHttpRequest对象时加一个特定的属性调用。

<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>

后端响应

<?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://caibaojian.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')); ?>

一些笔记:

浏览器支持:

Chrome 3+, Firefox 3.5+, IE 10+, Opera 12+, Safari 4+

兼容IE8的插件

https://github.com/MoonScript/jQuery-ajaxTransport-XDomainRequest

  • 1.只能是GET or POST请求,在使用post时,数据总是发送一个 Content-Type 为text/plain的
  • 2.只能是HTTP或者HTTPS,并且双方的协议需要一致
  • 3.总是使用异步请求

引入插件

<script type='text/javascript' src="http://cdnjs.cloudflare.com/ajax/libs/jquery-ajaxtransport-xdomainrequest/1.0.1/jquery.xdomainrequest.min.js"></script>

var contentType ="application/x-www-form-urlencoded; charset=utf-8";   if(window.XDomainRequest) //for IE8,IE9     contentType = "text/plain";   $.ajax({      url:"http://top.caibaojian.com/cross-domain-cors/post.php",      data:"name=Ravi&age=12",      type:"POST",      dataType:"json",         contentType:contentType,          success:function(data)      {         alert("Data from Server"+JSON.stringify(data));      },      error:function(jqXHR,textStatus,errorThrown)      {         alert("You can not send Cross Domain AJAX requests: "+errorThrown);      }  });

post.php代码

<?php header('Access-Control-Allow-Origin: *');  header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');   if(isset($HTTP_RAW_POST_DATA)) {   parse_str($HTTP_RAW_POST_DATA,$arr);    $arr['extra']='1.POST Request from caibaojian.com';   echo json_encode($arr); } else {     $_POST['extra']='2.POST Request from caibaojian.com';     echo json_encode($_POST); } ?>

网上太多的跨域解决方案了,我比较常用的就属JSONP和CORS了,对于IE系列的浏览器兼容,提交数据推荐使用iframe+form的方式

http://friedcell.si/js/jQuery.windowName/jQuery.windowName.plugin.js

以上代码参考:

  1. How to Send Cross Domain AJAX Request with jQuery
  2. Cross Domain AJAX Request
  3. 利用CORS实现跨域请求
文章来源: cors兼容性解决
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!