分享

ajax跨站请求方案

 WindySky 2016-11-17

ajax跨站请求方案

1:概述

跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的HTTP请求。出于安全考虑,浏览器会限制脚本中发起的跨站请求。比如,使用XMLHttpRequest对象发起 HTTP 请求就必须遵守同源策略。

 

2:方案

W3C的Web应用工作组推荐了一种新的机制,即跨源资源共享(Cross-Origin Resource Sharing(CORS))。这种机制让Web应用服务器能支持跨站访问控制,从而使得安全地进行跨站数据传输成为可能。比如说,要使得XMLHttpRequest在现代浏览器中可以发起跨域请求。浏览器必须能支持跨源共享带来的新的组件,包括请求头和策略执行。同样,服务器端则需要解析这些新的请求头,并按照策略返回相应的响应头以及所请求的资源。

 

3:实践(注:以下只是简单的测试用例)

3.1服务端

服务端定义一个Fitler来处理CORS,代码如下:

 

Java代码  收藏代码
  1. public class ApiCorsFilter implements Filter {  
  2.     @Override  
  3.     public void destroy() {  
  4.     }  
  5.     @Override  
  6.     public void init(FilterConfig filterConfig) throws ServletException {  
  7.     }  
  8.     @Override  
  9.     public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException {  
  10.         HttpServletResponse response = (HttpServletResponse) res;  
  11.         //允许所有外部资源访问,生产环境指定具体的站点提高安全  
  12.         response.setHeader("Access-Control-Allow-Origin", "*");  
  13.         //允许访问的方法类型,多个用逗号分隔  
  14.         response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  
  15.         //OPTIONS预请求缓存的有效时间 单位秒  
  16.         response.setHeader("Access-Control-Max-Age", "3600");  
  17.         //允许自定义的请求头,多个用逗号分隔  
  18.         response.setHeader("Access-Control-Allow-Headers", "content-type, x-requested-with");  
  19.         chain.doFilter(req, res);  
  20.     }  
  21. }  

 在项目的web.xml里配置Filter

 

Xml代码  收藏代码
  1. <filter>  
  2.     <filter-name>apiCorsFilter</filter-name>  
  3.     <filter-class>com.ihome.mobile.filter.ApiCorsFilter</filter-class>  
  4. </filter>  
  5. <filter-mapping>  
  6.     <filter-name>apiCorsFilter</filter-name>  
  7.     <url-pattern>/*</url-pattern>  
  8. </filter-mapping>  

 3.2客户端

编写一个ajax请求

 

Html代码  收藏代码
  1. <!DOCTYPE html>  
  2. <html>  
  3.     <head>  
  4.         <title>Hello cors</title>  
  5.         <script src="http://upcdn.b0./libs/jquery/jquery-1.10.2.min.js"></script>  
  6.         <script>  
  7.             $(function() {  
  8.                 $.ajax({  
  9.                     type: 'POST',  
  10.                     contentType : 'text/plain', //不会执行OPTIONS预请求  
  11. //                    contentType : 'application/json', //会执行OPTIONS预请求  
  12.                     url: "http://api.ldhome.",//内网虚拟映射地址  
  13.                     success: function(data){  
  14.                         $("#content").html(JSON.stringify(data));  
  15.                     },  
  16.                     error: function(state,xhr){  
  17.                         $("#content").html("请求失败");  
  18.                     }  
  19.                 });  
  20.             });  
  21.         </script>  
  22.     </head>  
  23.     <body>  
  24.         <h2>结果:</h2>  
  25.         <div id="content">  
  26.         </div>  
  27.     </body>  
  28. </html>  
 

 

测试结果1:没有预请求



 
可以看到上面只有post请求,请详细信息如下:



 

测试结果2:有预请求



 会发起OPTIONS请求,请求内容如下:



 预请求验证通过,才会发起POST的请求如下:



 

4:关于预请求(OPTIONS)

“预请求”要求必须先发送一个 OPTIONS 请求给目的站点,来查明这个跨站请求对于目的站点是不是安全可接受的。这样做,是因为跨站请求可能会对目的站点的数据造成破坏。 当请求具备以下条件,就会执行预请求处理:

  • 请求以GET,HEAD或者POST 以外的方法发起请求。或者,使用 POST,但contentTypeapplication/x-www-form-urlencoded, multipart/form-data或者text/plain 以外的数据类型。比如说,用 POST发送数据类型为application/json的JSON数据的请求。
  • 使用自定义请求头

 

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约