做有态度的前端团队

网易FEG前端团队

CORS跨域资源共享

前言:最近在后期优化梦幻西游手游图库项目的时候,遇到一个H5跨域请求接口的需求。

CORS-Orign Resource Sharing(CORS)既跨域资源共享,众所周知,浏览器有个同源策略,为了处理跨域请求,一般用JSONP,设置documet.domain降域,CORS等方式。
跨域资源共享协议标准通过声明一系列http标准头,让服务器能声明哪些来源可以通过浏览器范围服务器的资源。特别那些会对服务器数据造成影响的方法,标准要求浏览器要先以OPTION方法去发送一个预请求去获知服务器对跨源请求所支持的HTTP方法。以下就会分两种请求进行讨论。

1.简单请求
简单来说,就是一些请求不会触发CORS preflight(预请求的)。例如满足下述条件就是简单请求:

  • 请求是其中这三种方法之一 HEAD,POST,GET
  • 除了用户代理自动设置的头部外,,唯一允许人工设置的头部是是以下这几种情况 Accept,Accept-Language,Content-Language,Content-Type等。
  • 如果使用POST方法,允许Content-Type的值有application/x-www-form-urlencoded,multipart/form-data,text/plain

例如以下这个情景,在测试地址域名下http://test.nie.163.com/请求http://tuku-my.dev.webapp.163.com:8003/的接口,来获取相应的图片列表。

$.ajax({
    url : 'http://tuku-my.dev.webapp.163.com:8003/v1/image',
    data : {
        sort:'new',
        tag:'',
        start:0,
        span:20
    },
    type : 'GET',
    dataType : 'json',
    cache : true,
    xhrFields:{
        withCredentials : true
    },
    success : function(data){
        //do something
    },
    error : function(data){
        
    },
    complete : function(){

    }
})

接口请求的是json格式的数据,withCredentials设置为true,从而使得凭证信息(cookie)可以随着请求一起发送。

浏览器发出了哪些请求头

pic_3.png

如上图所示,在跨域资源共享时,浏览器可能发出这些请求头:

Origin:http://test.nie.163.com

origin参数是一个URI,告诉服务器端请求来自哪里。
这些请求头信息是在请求服务器端设置的,不需要手动设置。

在这个情景中,服务器返回了什么给浏览器
image_20170308183459.png

如上图所示,在跨域资源共享时,服务器需要返回的响应头信息如下:

Access-Control-Allow-Credentials:true

如果服务器的相应中没有这个响应头,则浏览器不会把请求的结果返回给发出请求的脚本程序,以保证信息安全。

Access-Control-Allow-Origin:http://test.nie.163.com
Vary:Origin

orgin参数表示允许向服务器发起请求的URI,如果不带Credentials可以设置为。但是如果指定了域名不是,就要设置vary响应头为origin,它告诉客户端,响应是根据不同请求头来返回内容的。
现在除了http://test.nie.163.com之外,其它站点不能跨域访问http://tuku-my.dev.webapp.163.com:8003/的内容了。

Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS

用来标明资源可被请求的方式

Access-Control-Allow-Headers:Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With

在实际请求中,标明可以使用的自定义的HTTP请求头。

2.非简单请求(有预请求)
如上面所述,不满足简单请求条件的,浏览器就会先发送一个方法为'OPTION'方法请求目的站点。来验证这个跨域请求对于目的站点是不是安全和可接受的。

例如在测试域名下http://test.nie.163.com/请求http://tuku-my.dev.webapp.163.com:8003/的接口,来删除已收藏的某相册。

$.ajax({
    url : 'http://tuku-my.dev.webapp.163.com:8003/v1/user/bookmarks',
    data : {
        album_id:'5860c2a98617ef3a0be83f42'
    },
    type : 'DELETE',
    dataType : 'json',
    cache : true,
    xhrFields:{
        withCredentials : true
    },
    success : function(data){
        //do something
    },
    error : function(data){
        
    },
    complete : function(){

    }
})

如图所示,此时浏览器会先发送一个OPTION方法的请求:
pic_4.png

查看方法为OPTION请求的头部:
pic_5.png


随着OPTION的请求,以下这两个请求头一起被发送:

Access-Control-Request-Headers:
Access-Control-Request-Method:DELETE

服务器返回的相关CORS的响应头有:

Access-Control-Allow-Credentials:true
Access-Control-Allow-Headers:Accept,Authorization,Cache-Control,Content-Type,DNT,If-Modified-Since,Keep-Alive,Origin,User-Agent,X-Mx-ReqToken,X-Requested-With
Access-Control-Allow-Methods:GET, POST, PUT, DELETE, OPTIONS
Access-Control-Allow-Origin:http://test.nie.163.com

对应的头部意思在上面已经叙述过,就不再重复了。
此时Access-Control-Allow-Origin的值是当前请求的域名得知允许访问,以及知道支持的请求方法和头部,然后浏览器进行了第二次的请求。


注意:使用jquery的$.ajax方法在跨域请求下没有发送X-Requested-With请求头,没跨域的时候可以看线上地址是有发送请求头

X-Requested-With:XMLHttpRequest

X-Requested-With这个请求可以判断客户端是Ajax请求还是其它请求,当值为XMLHttpRequest就说明是Ajax请求。
解决方法是可以在header里添加,在真正请求的时候就会发送这个头部。但实际情况是没必要加这个头部的。

headers: {'X-Requested-With': 'XMLHttpRequest'}

3.与JSONP不同的是,

  • JSONP只能支持GET的方式,承载信息量有限,CORS支持所有HTTP请求的类型。
  • CORS只兼容高级浏览器(浏览器需要支持HTML5),JSONP兼容低版本浏览器。
  • CORS是W3C标准化组织提出的一种规范机制,允许客户端的跨域请求。而jsonp是在html5之前,处理跨域的一种事实标准,但实际只是hack。

手机阅读请扫描下方二维码:

已有 58 条评论

  1. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  2. admin

    xiqpwrmtovtudzjdmatp

  3. admin|expr 998307486 + 924679820

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  4. admin%0d%0aCRLF-Header:CRLF-Value

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  5. xiqpwrmtovtudzjdmatp

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  6. admin&set /A 902068802+814261257

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  7. 12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  8. /*1*/{{904329798+952161477}}

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  9. ${927123812+971457320}

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  10. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  11. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  12. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  13. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  14. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  15. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  16. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  17. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  18. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  19. admin

    12345678 ali-40.gif ali-41.gif ali-42.gif ali-43.gif ali-44.gif ali-45.gif ali-46.gif ali-47.gif ali-48.gif ali-49.gif ali-50.gif ali-51.gif ali-53.gif ali-54.gif ali-55.gif ali-56.gif ali-57.gif ali-58.gif ali-59.gif ali-60.gif ali-61.gif

  20. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  21. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  22. 1

    555

  23. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  24. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  25. 1

    1

  26. 1

    1

  27. 1

    555

  28. 1

    1

  29. 1

    1

  30. 1

    1

  31. 1

    1

  32. 1

    1

  33. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  34. 1

    1 ali-40.gif ali-40.gif ali-41.gif ali-41.gif ali-42.gif ali-42.gif ali-43.gif ali-43.gif ali-44.gif ali-44.gif ali-45.gif ali-45.gif ali-46.gif ali-46.gif ali-47.gif ali-47.gif ali-48.gif ali-48.gif ali-49.gif ali-49.gif ali-50.gif ali-50.gif ali-51.gif ali-51.gif ali-52.gif ali-52.gif ali-53.gif ali-53.gif ali-54.gif ali-54.gif ali-55.gif ali-55.gif ali-56.gif ali-56.gif ali-57.gif ali-57.gif ali-58.gif ali-58.gif ali-59.gif ali-59.gif ali-60.gif ali-60.gif ali-61.gif ali-61.gif

  35. 1

    1

  36. 1

    555

  37. 1

    1

  38. 1

    1

  39. 1

    555

  40. 1

    1

  41. 1

    555

  42. 1

    1

  43. 1

    1

  44. 1

    1

  45. 1

    1

  46. 1

    1

添加新评论

ali-40.gifali-41.gifali-42.gifali-43.gifali-44.gifali-45.gifali-46.gifali-47.gifali-48.gifali-49.gifali-50.gifali-51.gifali-52.gifali-53.gifali-54.gifali-55.gifali-56.gifali-57.gifali-58.gifali-59.gifali-60.gifali-61.gif