您的位置:首页 > 其它

AJAX POST&跨域 解决方案 - CORS

2016-05-19 13:17 543 查看
一晃又到新年了,于是开始着手好好整理下自己的文档,顺便把一些自认为有意义的放在博客上,记录成点的点滴。
    


 

 
  跨域是我在日常面试中经常会问到的问题,这词在前端界出现的频率不低,主要原因还是由于安全限制(同源策略, 即JavaScript或Cookie只能访问同域下的内容),因为我们在日常的项目开发时会不可避免的需要进行跨域操作,所以跨域能力也算是前端工程师的基本功之一。
  和大多数跨域的解决方案一样,JSONP也是我的选择,可是某天PM的需求变了,某功能需要改成支持POST,因为传输的数据量比较大,GET形式搞不定。所以折腾了下闻名已久的CORS(跨域资源共享,Cross-Origin Resource Sharing,这边文章也就是折腾期间的小记与总结。
    


     

 

概述

CORS能做什么:

     正常使用AJAX会需要正常考虑跨域问题,所以伟大的程序员们又折腾出了一系列跨域问题的解决方案,如JSONP、flash、ifame、xhr2等等。
     本文介绍的CORS就是一套AJAX跨域问题的解决方案。
 

 CORS的原理:

     CORS定义一种跨域访问的机制,可以让AJAX实现跨域访问。CORS 允许一个域上的网络应用向另一个域提交跨域 AJAX 请求。实现此功能非常简单,只需由服务器发送一个响应标头即可。
 

CORS浏览器支持情况如下图:

      


    


  喜闻乐见、普大喜奔的支持情况,尤其是在移动终端上,除了opera Mini;
  PC上的现代浏览器都能友好的支持,除了IE9-,不过前端工程师对这种情况早应该习惯了...
    


 

CORS启航

 
  假设我们页面或者应用已在 http://www.test1.com 上了,而我们打算从 http://www.test2.com 请求提取数据。一般情况下,如果我们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来。
  利用 CORS,http://www.test2.com 只需添加一个标头,就可以允许来自 http://www.test1.com 的请求,下图是我在PHP中的 hander() 设置,“*”号表示允许任何域向我们的服务端提交请求
    


  也可以设置指定的域名,如域名 http://www.test2.com ,那么就允许来自这个域名的请求
    


     
  当前我设置的header为“*”,任意一个请求过来之后服务端我们都可以进行处理&响应,那么在调试工具中可以看到其头信息设置,其中见红框中有一项信息是“Access-Control-Allow-Origin:* ”,表示我们已经启用CORS,如下图。
  PS:由于demo都在我厂的两台测试机间完成,外网也不能访问,所以在这就不提供demo了,见谅

    


   简单的一个header设置,一个支持跨域&POST请求的server就完成了:)
 
  当然,如果没有开启CORS必定失败的啦,如下图:
  


问题&小结

刚刚说到的兼容性。CORS是W3C中一项较新的方案,所以部分浏览器还没有对其进行支持或者完美支持,详情可移至 http://www.w3.org/TR/cors/ 安全问题。CORS提供了一种跨域请求方案,但没有为安全访问提供足够的保障机制,如果你需要信息的绝对安全,不要依赖CORS当中的权限制度,应当使用更多其它的措施来保障,比如OAuth2。

 
  自认为的cors使用场景:

cors在移动终端支持的不错,可以考虑在移动端全面尝试;PC上有不兼容和没有完美支持,所以小心踩坑。当然浏览器兼容就是个伪命题,说不准某个浏览器的某个版本就完美兼容了,说不准就有点小坑,尼玛伤不起!~
jsonp是get形式,承载的信息量有限,所以信息量较大时CORS是不二选择;
配合新的JSAPI(fileapi、xhr2等)一起使用,实现强大的新体验功能。

 
  如果觉得这文章也算用心,请劳驾点右下角的推荐。
  祝2014顺利。
 
  最后,有 北京&上海 的朋友想春节后想换工作的,【百度移动云事业部】期待聪明、勤奋的你 与我联系 (JD在页面右上角)
 
参考资料:
          http://www.w3.org/TR/cors/
          http://www.html5rocks.com/en/tutorials/cors/
          http://caniuse.com/#search=cors
 
 

作者:聂微东

出处:http://www.cnblogs.com/Darren_code/

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

好文要顶关注我
收藏该文联系我







聂微东
关注 - 29
粉丝 - 2229

荣誉:推荐博客
+加关注

64
1

(请您对文章做出评价)

«上一篇:数据工作-百度统计初体验
»下一篇:Nodejs初阶之express

分类:
HTML5,
学习笔记
标签:
HTML5

Add your comment

#1楼magicdawn

  2014-01-06 13:05

就是加一个header的啊,可是post 的action地址那页面要不是你能修改的,怎么弄...

昨天碰到一个问题http://xhj.douqq.com/这是一个小黄鸡的页面,是post提交chat参数,想借过来用用,结果就碰到了那个错误...

最后用服务器中转的,写个玩玩http://magicdawn.apphb.com/Simsimi

中转用webrequest,感觉特么费劲,请求服务器,服务器再webrequest,再把webresponse写到这个response里面...费劲,又浪费服务器资源...有什么好方法木有呢
支持(0)反对(0) http://pic.cnblogs.com/face/524870/20130505173323.png
#2楼magicdawn

  2014-01-06 13:11

我那个小黄鸡中转接口http://magicdawn.apphb.com/Simsimi/Agent?chat=xxx
支持(0)反对(0) http://pic.cnblogs.com/face/524870/20130505173323.png
#3楼[楼主]聂微东

  2014-01-06 16:09

@ magicdawn

如果post页面不能改或者不知道CORS,那这套方案就不行了。

至于你写的玩玩那个东西,木有神马建议,不明觉厉:)
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#4楼[楼主]聂微东

  2014-01-06 16:13

@ magicdawn

想了半天,你想借用别人的接口搞这个东西,不用webrequest我也没有别的方法了,看看你再多问问其他人试试。没帮上忙,略惭愧。
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#5楼magicdawn

  2014-01-06 18:44

@ 聂微东

哦,看到有个Apache rewrite proxy规则的教程,不知道IIS咋弄
支持(0)反对(0) http://pic.cnblogs.com/face/524870/20130505173323.png
#6楼[楼主]聂微东

  2014-01-07 11:07

@ magicdawn

apache真心不懂了,加油。
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#7楼何戈洲

  2014-01-08 10:18

多谢分享,那天试了下这个方案,发现不管用,不知道是怎么回事,不清楚是不是浏览器不支持
支持(0)反对(0) http://pic.cnblogs.com/face/u46256.jpg?id=24205029
#8楼[楼主]聂微东

  2014-01-10 11:50

@ 何戈洲

浏览器支持情况在文章中有提到,现代浏览器都支持的,你看看调式工具中header是否设置成功了。
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#9楼SharpLW

  2014-07-07 07:42

你好。我试了你的办法,可以用。但有没有通过Ajax传数据到服务器的例子呢。
支持(0)反对(0)

#10楼网名还没想好

  2014-10-17 11:07

爱好dota~
支持(0)反对(0) http://pic.cnblogs.com/face/355147/20150603191620.png
#11楼Leeeex

  2014-11-03 01:49

这样的跨域是收发数据吗?能跨站点操作JS方法吗,例如A站点页面为父窗口,打开子窗口B站点的页面。然后B站点的页面能跨域操作A站点页面的方法么。

就像A站点页面有个JS方法siteA();B站点执行parent.window.siteA(),这样能执行成功么?
支持(0)反对(0)

#12楼zhoushen刀一个

  2015-03-06 16:37

我是python 后台, 设置了cors 的功能。

目前前端get请求能请求成功,post却是403.

我对前端真心不懂,请问有没有注意事项。。。
支持(0)反对(0)

#13楼zhoushen刀一个

  2015-03-06 16:39

GET http://sso.acttao.com:8888/cas/login/?service=%2Fauth%2Flogin%2F&email=&password=&next=
200 OK

36ms

jquery-1.8.2.js (第 8416 行)

参数头信息响应HTMLCookies

原始头信息

Access-Control-Allow-Cred... true

Access-Control-Allow-Orig... http://zgxcw.acttao.com:8002
Cache-Control max-age=0
支持(0)反对(0)

#14楼zhoushen刀一个

  2015-03-06 16:41

403 FORBIDDEN

32ms

jquery-1.8.2.js (第 8416 行)

头信息Post响应HTML

原始头信息

Access-Control-Allow-Cred... true

Access-Control-Allow-Orig... http://zgxcw.acttao.com:8002
Content-Type text/html

Date Fri, 06 Mar 2015 08:40:54 GMT

Server WSGIServer/0.1 Python/2.7.6

Vary Cookie
支持(0)反对(0)

#15楼夜明兔

  2015-04-13 00:37

中文冒号害死人啊 -_-||
支持(0)反对(0)

#16楼[楼主]聂微东

  2015-04-13 14:25

@ 夜明兔

这, 额...-_-||
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#17楼mrma1989

  2015-04-23 14:12

ajax post请求,发现不发送cookies了呢
支持(0)反对(0)

#18楼键盘2

  2015-05-27 11:11

楼主大哥,我现在需要一个域名的所有的二级域名都可以发送请求,不知道要怎么设置呢?除了用*号还有什么办法吗?
支持(0)反对(0)

#19楼颜传

  2015-07-02 10:08

弱弱的问一句:跨域究竟是浏览器不允许发送跨域请求还是浏览器不允许接受跨域响应呢?看这个情况,只是修改了服务端access-control-allow-origin,应该只是不允许收响应吧?还是因为开启core部分没看到,其实浏览器也不允许发请求,开启了才允许发?
支持(0)反对(0)

#20楼[楼主]聂微东

  2015-07-02 11:45

同源策略理解了就好,看看这个文章:http://www.cnblogs.com/huangjacky/p/4001073.html
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#21楼天涯过者

  2015-07-03 09:19

直接数据返回是callback(json)也是可以的呢
支持(0)反对(0) http://pic.cnblogs.com/face/663962/20150703135050.png
#22楼MasonZhang

  2015-07-22 15:56

很流畅,清晰易懂!
支持(0)反对(0) http://pic.cnblogs.com/face/489086/20151102165608.png
#23楼[楼主]聂微东

  2015-07-31 08:13

@ miketwais

谢谢支持:)
支持(0)反对(0) http://pic.cnblogs.com/face/u159097.jpg
#24楼猪儿闹闹

  2015-09-16 11:22

"假设我们页面或者应用已在test1.com 上了,而我们打算从 test2.com 请求提取数据。一般情况下,如果我们直接使用 AJAX 来请求将会失败,浏览器也会返回“源不匹配”的错误,"跨域"也就以此由来。

  利用 CORS,test2.com 只需添加一个标头,就可以允许来自 test1.com 的请求,下图是我在PHP中的 hander() 设置,“*”号表示允许任何域向我们的服务端提交请求"

您好 第二段的test1和test2的例子是不是写反了,第一段说应用已在 test1.com 上,打算从test2.com请求,但第二段却说给test2.com 只需添加一个标头,就可以允许来自test1.com 的请求,下面截图又说也可以设置指定的域名,如域名 test2.com ,那么就允许来自这个域名的请求...

我理解时header是设置在test1上,使其可接受test2发来的跨域请求吧,以此推断第二段段落是不是写反了
支持(2)反对(0)

#25楼vloner

  2016-01-18 11:53

@ 猪儿闹闹

我想应该是写错了
支持(0)反对(0)

#26楼34123972016/4/19
19:45:15
王伟嵩
  2016-04-19 19:45

我在服务器上设置头域的代码,options请求进不来是为什么呢?options请求都到不了我设置头域的代码这里,不清楚请求是在哪个地方过不来= =
支持(0)反对(0)

刷新评论刷新页面返回顶部

注册用户登录后才能发表评论,请
登录 或
注册,访问网站首页。

【推荐】50万行VC++源码: 大型组态工控、电力仿真CAD与GIS源码库
【推荐】融云即时通讯云-豆果美食、Faceu等亿级APP都在用
【推荐】怎样将“在线Excel“嵌入你的开发系统中?
【推荐】阿里云万网域名:.xin .com将推出重磅优惠
【活动】开发交流会:当轻架构前端撞上高性能大数据后台
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: