版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
1、JS跨域访问解决方案总结0引言:跨域请求,顾名思义,就是一个站点中的资源去访问另外一个不同域名站点上的资源。这种情况很常见,比如说通过style标签加载外部样式表文件、通过 img 标签加载外部图片、通过 script 标签加载外部脚本文件、通过 Web font 加载字体文件等等。默认情况下,脚本访问文档属性等数据采用的是同源策略(Same origin policy)。同源策略:如果两个页面的协议、域名和端口是完全相同的,那么它们就是同源的。同源策略是为了防止从一个地址加载的文档或脚本访问或者设置从另外一个地址加载的文档的属性。如果两个页面的主域名相同,则还可以通过设置document.d
2、omain 属性将它们认为是同源的。随着 Web2.0 和 SNS 的兴起,Web 应用对跨域访问的需求也越来越多,但在脚本中进行跨域请求是受安全性限制的,Web 开发人员迫切需要提供一种更安全、方便的跨域请求方式来融合(Mashup)自己的 Web 应用。这样做的一个好处就是可以将请求分摊到不同的服务器,减轻单个服务器压力以提高响应速度;另外一个好处是可以将不同的业务逻辑分布到不同的服务器上以降低负载。值得庆幸的是,跨域请求的标准已经出台,主流浏览器也已经实现了这一标准。W3C 工作组中的 Web Applications Working Group(Web 应用工作组)发布了一个 Cros
3、s-Origin Resource Sharing(跨域资源共享规范)推荐规范来解决跨域请求的问题。该规范提供了一种更安全的跨域数据交换方法。具体规范的介绍可以访问上面提供的网站地址。值得注意的是:该规范只能应用在类似XMLHttprequest 这样的 API 容器内。IE8、Firefox 3.5 及其以后的版本、Chrome浏览器、Safari 4 等已经实现了 Cross-Origin Resource Sharing 规范,已经可以进行跨域请求了。一、支持跨域访问处理浏览器Cross-Origin Resource Sharing 的工作方式是通过添加 HTTP 头的方法来判断哪些资
4、源允许 Web 浏览器访问该域名下的信息。然而,对于那些 HTTP 请求导致用户数据产生副作用的请求方法(特别是对于除了GET、某些 MIME 类型的 POST 之外的 HTTP方法),该规范要求浏览器对请求进行“预先验”,通过发送 HTTP 的 OPTIONS 请求头询问服务器有哪些支持的方法,在征得服务器的同意后,再使用实际的 HTTP 请求方法发送实际的请求。服务器也可以通知客户端是否需要将验证信息(如 Cookie 和 HTTP Authentication 数据)随同请求一起发送。下面我们就采用实际的例子说明 Cross-Origin Resource Sharing 是如何工作的。
5、1,简单请求什么样的请求算是简单请求呢?简单请求必须满足下面2点:a,只使用 GET、POST 进行的请求,这里的POST只包括发送给服务器的数据类型(Content-Type)必须是 application/x-www-form-urlencoded、multipart/form-data 或者 text/plain中一个。b,HTTP 请求没有设置自定义的请求头,如我们常用的 X-JSON。先使用下面的代码进行测试:XML/HTML代码1. 3. 4. 5. 孟宪会之AJAX跨域请求测试 6. 7. 8. 9. 10. !- 11. varxhr=newXMLHttpRequest();
6、12. varurl=http:/dotnet.aspx.cc/SimpleCrossSiteRequests.aspx; 13. functioncrossDomainRequest() 14. document.getElementById(content).innerHTML=开始; 15. if(xhr) 16. xhr.open(GET,url,true); 17. xhr.onreadystatechange=handler; 18. xhr.send(); 19. else 20. document.getElementById(content).innerHTML=不能创建XM
7、LHttpRequest; 21. 22. 23. functionhandler(evtXHR) 24. if(xhr.readyState=4) 25. if(xhr.status=200) 26. varresponse=xhr.responseText; 27. document.getElementById(content).innerHTML=结果:+response; 28. else 29. document.getElementById(content).innerHTML=不允许跨域请求。; 30. 31. 32. else 33. document.getElementB
8、yId(content).innerHTML+=执行状态readyState:+xhr.readyState; 34. 35. 36. /- 37. 38. 然后,在服务器创建 CrossDomainRequest.aspx 的内容如下:C# 代码1. 2. 点击 “开始测试” 按钮,发送的请求和返回的响应信息如下:XML/HTML代码1. GET/SimpleCrossSiteRequests.aspxHTTP/1.1 2. Host:dotnet.aspx.cc 3. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:1.9.1.
9、7)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 4. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5. Accept-Language:zh-cn,zh;q=0.5 6. Accept-Encoding:gzip,deflate 7. Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 8. Keep-Alive:300 9. Connection:keep-alive 10. Referer:http:/www.meng_xian_
10、:801/CrossDomainAjax/SimpleCrossSiteRequests.html 11. Origin:http:/www.meng_xian_:801 12. HTTP/1.x200OK 13. Date:Sun,10Jan201013:52:00GMT 14. Server:Microsoft-IIS/6.0 15. X-Powered-By:ASP.NET 16. X-AspNet-Version:2.0.50727 17. Access-Control-Allow-Origin:http:/www.meng_xian_:801
11、 18. Set-Cookie:ASP.NET_SessionId=wk5v5nrs5wbfi4rmpjy2jujb;path=/;HttpOnly 19. Cache-Control:private 20. Content-Type:text/html;charset=utf-8 21. Content-Length:84 需要特别注意的是:在请求信息中,浏览器使用 Origin 这个 HTTP 头来标识该请求来自于 http:/www.meng_xian_:801;在返回的响应信息中,使用 Access-Control-Allow-Origin 头来控制哪些域名的脚本可以访问
12、该资源。如果设置 Access-Control-Allow-Origin:*,则允许所有域名的脚本访问该资源。如果有多个,则只需要使用逗号分隔开即可。注意:在服务器端,Access-Control-Allow-Origin 响应头 http:/www.meng_xian_:801 中的端口信息不能省略。有人可能会想:自己发送请求头会如何呢?比如 xhr.setRequestHeader(Origin,http:/www.meng_xian_:801); 实践证明,自己设置 Origin 头是不行的。是不是现在就可以采用 XMLHttpRequest 来请求任意一个网
13、站的数据呢?还是不行的。允许哪些域名可以访问,还需要服务器来设置 Access-Control-Allow-Origin 头来进行授权,具体的代码是:Response.AddHeader(Access-Control-Allow-Origin, http:/www.meng_xian_:801);这行代码就告诉浏览器,只有来自 http:/www.meng_xian_:801 源下的脚本才可以进行访问。好了,上面我们就完成了一个简单的跨域请求,怎么样?感觉还是不错的吧。下面我们进行一个“预检”请求。2,预检请求预检请求首先需要向另外一个域名的资源发送一个 HTTP
14、OPTIONS 请求头,其目的就是为了判断实际发送的请求是否是安全的。下面的2种情况需要进行预检:a,不是上面的简单请求,比如使用Content-Type 为 application/xml 或 text/xml 的 POST 请求b,在请求中设置自定义头,比如 X-JSON、X-MENGXIANHUI 等注意:在 iis 里进行测试,必须在“应用程序扩展”里面配置 .aspx 扩展的动作允许 OPTIONS。下面我们举一个预检的请求:XML/HTML代码1. 3. 4. 5. 孟宪会之AJAX跨域请求测试 6. 7. 8. 9. 10. !- 11. varxhr=newXMLHttpReq
15、uest(); 12. varurl=http:/dotnet.aspx.cc/PreflightedRequests.aspx; 13. functioncrossDomainRequest() 14. document.getElementById(content).innerHTML=开始进行请求; 15. if(xhr) 16. varxml=测试; 17. xhr.open(POST,url,true); 18. xhr.setRequestHeader(POWERED-BY-MENGXIANHUI,Approve); 19. xhr.setRequestHeader(Content
16、-Type,application/xml); 20. xhr.onreadystatechange=handler; 21. xhr.send(xml); 22. else 23. document.getElementById(content).innerHTML=不能创建XMLHttpRequest。; 24. 25. 26. functionhandler(evtXHR) 27. if(xhr.readyState=4) 28. if(xhr.status=200) 29. varresponse=xhr.responseText; 30. document.getElementByI
17、d(content).innerHTML=结果:+response; 31. else 32. document.getElementById(content).innerHTML=不能进行跨越访问。; 33. 34. 35. else 36. document.getElementById(content).innerHTML+=执行状态readyState:+xhr.readyState; 37. 38. 39. /- 40. 41. 上面的例子我们发送 xml 格式的数据,并且,发送一个非标准的HTTP头 POWERED-BY-MENGXIANHUI 来说明服务器端该如何设置响应头的。在
18、服务器端,PreflightedRequests.aspx 的内容如下:C#代码1. 2. !- 3. protectedvoidPage_Load(objectsender,EventArgse) 4. 5. if(Request.HttpMethod.Equals(GET) 6. 7. Response.Write(这个页面是用来测试跨域POST请求的,直接浏览意义不大。); 8. 9. elseif(Request.HttpMethod.Equals(OPTIONS) 10. 11. /通知客户端允许预检请求。并设置缓存时间 12. Response.ClearContent(); 13
19、. Response.AddHeader(Access-Control-Allow-Origin,http:/www.meng_xian_:801); 14. Response.AddHeader(Access-Control-Allow-Methods,POST,GET,OPTIONS); 15. Response.AddHeader(Access-Control-Allow-Headers,POWERED-BY-MENGXIANHUI); 16. Response.AddHeader(Access-Control-Max-Age,30); 17. /此过程无需返回数据 18.
20、 Response.End(); 19. 20. elseif(Request.HttpMethod.Equals(POST) 21. 22. if(Request.HeadersOrigin.Equals(http:/www.meng_xian_:801) 23. 24. System.Xml.XmlDocumentdoc=newSystem.Xml.XmlDocument(); 25. doc.Load(Request.InputStream); 26. Response.AddHeader(Access-Control-Allow-Origin,http:/www.meng
21、_xian_:801); 27. Response.Write(您提交的数据是:+Server.HtmlEncode(doc.OuterXml); 28. 29. else 30. 31. Response.Write(不允许你的网站请求。); 32. 33. 34. 35. /- 点击“开始测试”按钮,将会执行下面的一系列请求。XML/HTML代码1. OPTIONS/PreflightedRequests.aspxHTTP/1.1 2. Host:dotnet.aspx.cc 3. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;z
22、h-CN;rv:)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 4. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5. Accept-Language:zh-cn,zh;q=0.5 6. Accept-Encoding:gzip,deflate 7. Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 8. Keep-Alive:300 9. Connection:keep-alive 10. Origin:http:/w
23、ww.meng_xian_:801 11. Access-Control-Request-Method:POST 12. Access-Control-Request-Headers:powered-by-mengxianhui 13. HTTP/1.x200OK 14. Date:Sun,10Jan201014:00:34GMT 15. Server:Microsoft-IIS/6.0 16. X-Powered-By:ASP.NET 17. X-AspNet-Version:2.0.50727 18. Access-Control-Allow-Origin:http:/www
24、.meng_xian_:801 19. Access-Control-Allow-Methods:POST,GET,OPTIONS 20. Access-Control-Allow-Headers:POWERED-BY-MENGXIANHUI 21. Access-Control-Max-Age:30 22. Set-Cookie:ASP.NET_SessionId=5npqri55dl1k1zvij1tlw3re;path=/;HttpOnly 23. Cache-Control:private 24. Content-Length:0 25. POST/Preflighted
25、Requests.aspxHTTP/1.1 26. Host:dotnet.aspx.cc 27. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 28. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 29. Accept-Language:zh-cn,zh;q=0.5 30. Accept-Encoding:gzip,deflate 31. Ac
26、cept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 32. Keep-Alive:300 33. Connection:keep-alive 34. POWERED-BY-MENGXIANHUI:Approve 35. Content-Type:application/xml;charset=UTF-8 36. Referer:http:/www.meng_xian_:801/CrossDomainAjax/PreflightedRequests.html 37. Content-Length:19 38. Origin:http:/www.meng_
27、xian_:801 39. Pragma:no-cache 40. Cache-Control:no-cache 41. 测试 42. HTTP/1.x200OK 43. Date:Sun,10Jan201014:00:34GMT 44. Server:Microsoft-IIS/6.0 45. X-Powered-By:ASP.NET 46. X-AspNet-Version:2.0.50727 47. Access-Control-Allow-Origin:http:/www.meng_xian_:801 48. Set-Cookie:ASP.NET_Sessi
28、onId=byvose45zmtbqy45d2a1jf2i;path=/;HttpOnly 49. Cache-Control:private 50. Content-Type:text/html;charset=utf-8 51. Content-Length:65 以上的代码反映了预检请求的执行过程:首先发送 OPTIONS 请求头,用来向服务器咨询服务器的更多信息,以便为后续的真实请求做准备。比如是否支持 POST 方法等。值得注意的是:浏览器还发送Access-Control-Request-Method: POST 和 Access-Control-Request-Headers:
29、powered-by-mengxianhui 请求头。注意:以上过程是第一次请求的时候的过程,如果在 30 秒内重复点击按钮,你可以看不到 OPTIONS 这一过程。则执行过程是这样的:XML/HTML代码1. POST/PreflightedRequests.aspxHTTP/1.1 2. Host:dotnet.aspx.cc 3. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 4. Accept:text/html,applicati
30、on/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5. Accept-Language:zh-cn,zh;q=0.5 6. Accept-Encoding:gzip,deflate 7. Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 8. Keep-Alive:300 9. Connection:keep-alive 10. POWERED-BY-MENGXIANHUI:Approve 11. Content-Type:application/xml;charset=UTF-8 12. Referer:http:/w
31、ww.meng_xian_:801/CrossDomainAjax/PreflightedRequests.html 13. Content-Length:19 14. Origin:http:/www.meng_xian_:801 15. Pragma:no-cache 16. Cache-Control:no-cache 17. 测试 18. HTTP/1.x200OK 19. Date:Sun,10Jan201014:06:32GMT 20. Server:Microsoft-IIS/6.0 21. X-Powered-By:ASP.NET 22. X-Asp
32、Net-Version:2.0.50727 23. Access-Control-Allow-Origin:http:/www.meng_xian_:801 24. Set-Cookie:ASP.NET_SessionId=qs1c4urxywdbdx55u04pvual;path=/;HttpOnly 25. Cache-Control:private 26. Content-Type:text/html;charset=utf-8 27. Content-Length:65 为什么会这样?细心的同学可能注意到了,在服务器端有一行代码 Response.AddHeader(Ac
33、cess-Control-Max-Age, 30); 它是用来设置预检的有效时间的,单位是秒。这一点要特别注意。3,带验证信息的请求身份验证是Web开发中经常遇到的问题,在跨域请求中,默认情况下是不发送验证信息的。要想发送验证信息,需要进行withCredentials 属性,下面就是一个简单请求的例子:XML/HTML代码1. 3. 4. 5. 孟宪会之AJAX跨域请求测试 6. 7. 8. 9. 10. !- 11. varxhr=newXMLHttpRequest(); 12. varurl=http:/dotnet.aspx.cc/RequestsWithCredentials.asp
34、x; 13. functioncrossDomainRequest() 14. document.getElementById(content).innerHTML=开始进行请求; 15. if(xhr) 16. xhr.open(GET,url,true); 17. xhr.onreadystatechange=handler; 18. xhr.withCredentials=true; 19. xhr.send(); 20. else 21. document.getElementById(content).innerHTML=不能创建XMLHttpRequest。; 22. 23. 24
35、. functionhandler(evtXHR) 25. if(xhr.readyState=4) 26. if(xhr.status=200) 27. varresponse=xhr.responseText; 28. document.getElementById(content).innerHTML=结果:+response; 29. else 30. document.getElementById(content).innerHTML+=执行状态status:+xhr.status; 31. 32. 33. else 34. document.getElementById(conte
36、nt).innerHTML+=执行状态readyState:+xhr.readyState; 35. 36. 37. /- 38. 39. 点击“开始测试”,我们可以检测到下面的请求执行过程:XML/HTML代码1. GET/RequestsWithCredentials.aspxHTTP/1.1 2. Host:dotnet.aspx.cc 3. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 4. Accept:text/html,app
37、lication/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5. Accept-Language:zh-cn,zh;q=0.5 6. Accept-Encoding:gzip,deflate 7. Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 8. Keep-Alive:300 9. Connection:keep-alive 10. Referer:http:/www.meng_xian_:801/CrossDomainAjax/RequestsWithCredentials.html 11. Or
38、igin:http:/www.meng_xian_:801 12. HTTP/1.x200OK 13. Date:Sun,10Jan201014:12:26GMT 14. Server:Microsoft-IIS/6.0 15. X-Powered-By:ASP.NET 16. X-AspNet-Version:2.0.50727 17. Access-Control-Allow-Origin:http:/www.meng_xian_:801 18. Access-Control-Allow-Credentials:true 19. Set-Cookie:ASP.N
39、ET_SessionId=fn2zf0zq1cuwgf45fm5fw145;path=/;HttpOnly 20. Set-Cookie:visit=1;expires=Sun,10-Jan-201014:12:56GMT;path=/ 21. Cache-Control:no-cache 22. Pragma:no-cache 23. Expires:-1 24. Content-Type:text/html;charset=utf-8 25. Content-Length:1 从上面的响应中可以看出,Cookie 是会随请求一起发送的。如果我们多次点击测试按钮,则可以看到请求和响应的结果是
40、这样的:XML/HTML代码1. GET/RequestsWithCredentials.aspxHTTP/1.1 2. Host:dotnet.aspx.cc 3. User-Agent:Mozilla/5.0(Windows;U;WindowsNT5.2;zh-CN;rv:)Gecko/Firefox/3.5.7(.NETCLR3.5.30729) 4. Accept:text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 5. Accept-Language:zh-cn,zh;q=0.5 6. Acce
41、pt-Encoding:gzip,deflate 7. Accept-Charset:GB2312,utf-8;q=0.7,*;q=0.7 8. Keep-Alive:300 9. Connection:keep-alive 10. Referer:http:/www.meng_xian_:801/CrossDomainAjax/RequestsWithCredentials.html 11. Origin:http:/www.meng_xian_:801 12. Cookie:ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145;v
42、isit=2 13. HTTP/1.x200OK 14. Date:Sun,10Jan201014:13:58GMT 15. Server:Microsoft-IIS/6.0 16. X-Powered-By:ASP.NET 17. X-AspNet-Version:2.0.50727 18. Access-Control-Allow-Origin:http:/www.meng_xian_:801 19. Access-Control-Allow-Credentials:true 20. Set-Cookie:visit=3;expires=Sun,10-Jan-201014:1
43、4:28GMT;path=/ 21. Cache-Control:no-cache 22. Pragma:no-cache 23. Expires:-1 24. Content-Type:text/html;charset=utf-8 25. Content-Length:1 注意 Cookie: ASP.NET_SessionId=fn2zf0zq1cuwgf45fm5fw145; visit=2 这一行,访问计数器已经被一起发送到服务器。4,IE8中的实现方法IE8已经开始支持跨域访问资源了,但是,IE8提供的功能还比较简单,可以进行简单的请求,下面是一个使用的例子:XML/HTML代码1. 3. 4. 5. 孟宪会之AJAX跨域请求测试 6. 7. 8. 9. 10. 27. 28. 另外,IE8的实现方法与其他浏览器不同。更多内容请参考 XDomainRequest 对象,地址是:/zh-cn
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2026下半年高中语文教资面试作文重难点题库
- 2026年辽宁省新民市高三数学下册期末考试模拟卷附参考答案(预热题)
- 2026年浙江省瑞安市高三数学下册期末考试模拟卷(培优B卷)附答案
- 2026年广东省阳春市高三数学下册期末考试模拟考试卷【综合卷】附答案
- 2026年福建省邵武市高三数学下册期末考试模拟检测卷附参考答案(完整版)
- 2026年江苏省张家港市高三数学下册期末考试模拟考试卷带答案(新)
- 2026年安徽省巢湖市高三数学下册期末考试模拟考试卷附参考答案(预热题)
- 艺术家创作绩效评定表
- 广告视觉设计团队领导评估表
- 办公室装修进展催办函(5篇)
- 2026“外研社·国才杯”“理解当代中国”外语能力国际传播综合能力赛项真题及答案解析(10月11日上午场次)
- 2026年七年级数学竞赛试题及答案
- 河南2027届高三年级过程性作业评价(青桐鸣)联考数学+答案
- 昭通市2026年市直事业单位公开选调工作人员(42人)笔试参考题库及答案解析
- 学堂在线 批判性思维-方法和实践 章节测试答案
- 小学生课间游戏课件
- tb-10314-2021《邻近铁路营业线施工安全监测技术规程》内容解析
- 护林员考试试题及答案
- 煤矿20版标准化-瓦斯参数测定管理制度
- 研究生职业规划与求职攻略智慧树知到答案2024年东北林业大学
- HG∕T 5055-2016 锂电池电极保护胶粘带
评论
0/150
提交评论