利用CORS实现POST方式跨域请求数据

CORS全名Cross-Origin Resource Sharing,顾名思义:跨域分享资源,这是W3C制定的跨站资源分享标准。

目前包括IE10+、chrome、safari、FF都提供了XMLHttpRequest对象对该标准的支持,在更老的IE8中则提供了xDomainRequest对象,部分实现了该标准;

下面是创建request对象的代码:

  1. var url = "http://www.phpfensi.com/1.php";
  2. if (XMLHttpRequest) {
  3. var req = new XMLHttpRequest();
  4. // 利用withCredentials属性来判断是否支持跨域请求
  5. if (!("withCredentials" in req)) { // w3c先行
  6. if (window.XDomainRequest) {
  7. req = new XDomainRequest();
  8. }
  9. }
  10. req.open('POST', url, true);
  11. req.onload = function (data) {
  12. alert(this.responseText);
  13. };
  14. req.send();
  15. }

注意xDomainRequest对象只支持http和https协议

在利用XMLHttpRequest对象发POST请求前会发一个options嗅探来确定是否有跨域请求的权限;同时在header头上带上Origin信息来指示来源网站信息,服务器响应时需要带上Access-Control-Allow-Origin头的值是否和Origin信息相匹配。

header("Access-Control-Allow-Origin: http://localhost"); // *为全部域名

CORS的缺点是你必须能控制服务器端的权限,允许你跨域访问

设置CORS实现跨域请求

一、使用php代码实现

  1. #
  2. # CORS config for php
  3. # Code by anrip[mail@anrip.com]
  4. #
  5. function make_cors($origin = '*') {
  6. $request_method = $_SERVER['REQUEST_METHOD'];
  7. if ($request_method === 'OPTIONS') {
  8. header('Access-Control-Allow-Origin:'.$origin);
  9. header('Access-Control-Allow-Credentials:true');
  10. header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
  11. header('Access-Control-Max-Age:1728000');
  12. header('Content-Type:text/plain charset=UTF-8');
  13. header('Content-Length: 0',true);
  14. header('status: 204');
  15. header('HTTP/1.0 204 No Content');
  16. }
  17. if ($request_method === 'POST') {
  18. header('Access-Control-Allow-Origin:'.$origin);
  19. header('Access-Control-Allow-Credentials:true');
  20. header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
  21. }
  22. if ($request_method === 'GET') {
  23. header('Access-Control-Allow-Origin:'.$origin);
  24. header('Access-Control-Allow-Credentials:true');
  25. header('Access-Control-Allow-Methods:GET, POST, OPTIONS');
  26. }
  27. }

二、使用nginx配置实现

  1. # CORS config for nginx
  2. # Code by anrip[mail@anrip.com]
  3. #
  4. location / {
  5. set $origin '*';
  6. if ($request_method = 'OPTIONS') {
  7. add_header 'Access-Control-Allow-Origin' $origin;
  8. #
  9. # Om nom nom cookies
  10. #
  11. add_header 'Access-Control-Allow-Credentials' 'true';
  12. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  13. #
  14. # Custom headers and headers various browsers *should* be OK with but aren't
  15. #
  16. add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  17. #
  18. # Tell client that this pre-flight info is valid for 20 days
  19. #
  20. add_header 'Access-Control-Max-Age' 1728000;
  21. add_header 'Content-Type' 'text/plain charset=UTF-8';
  22. add_header 'Content-Length' 0;
  23. return 204;
  24. }
  25. if ($request_method = 'POST') {
  26. add_header 'Access-Control-Allow-Origin' $origin;
  27. add_header 'Access-Control-Allow-Credentials' 'true';
  28. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  29. add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  30. }
  31. if ($request_method = 'GET') {
  32. add_header 'Access-Control-Allow-Origin' $origin;
  33. add_header 'Access-Control-Allow-Credentials' 'true';
  34. add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
  35. add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
  36. }
  37. }