ajax跨站请求方案
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,代码如下:
public class ApiCorsFilter implements Filter { @Override public void destroy() { } @Override public void init(FilterConfig filterConfig) throws ServletException { } @Override public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) res; //允许所有外部资源访问,生产环境指定具体的站点提高安全 response.setHeader("Access-Control-Allow-Origin", "*"); //允许访问的方法类型,多个用逗号分隔 response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE"); //OPTIONS预请求缓存的有效时间 单位秒 response.setHeader("Access-Control-Max-Age", "3600"); //允许自定义的请求头,多个用逗号分隔 response.setHeader("Access-Control-Allow-Headers", "content-type, x-requested-with"); chain.doFilter(req, res); } }
在项目的web.xml里配置Filter
<filter> <filter-name>apiCorsFilter</filter-name> <filter-class>com.ihome.mobile.filter.ApiCorsFilter</filter-class> </filter> <filter-mapping> <filter-name>apiCorsFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
3.2客户端
编写一个ajax请求
<!DOCTYPE html> <html> <head> <title>Hello cors</title> <script src="http://upcdn.b0.upaiyun.com/libs/jquery/jquery-1.10.2.min.js"></script> <script> $(function() { $.ajax({ type: 'POST', contentType : 'text/plain', //不会执行OPTIONS预请求 // contentType : 'application/json', //会执行OPTIONS预请求 url: "http://api.ldhome.com.net",//内网虚拟映射地址 success: function(data){ $("#content").html(JSON.stringify(data)); }, error: function(state,xhr){ $("#content").html("请求失败"); } }); }); </script> </head> <body> <h2>结果:</h2> <div id="content"> </div> </body> </html>
测试结果1:没有预请求
可以看到上面只有post请求,请详细信息如下:
测试结果2:有预请求
会发起OPTIONS请求,请求内容如下:
预请求验证通过,才会发起POST的请求如下:
4:关于预请求(OPTIONS)
“预请求”要求必须先发送一个 OPTIONS 请求给目的站点,来查明这个跨站请求对于目的站点是不是安全可接受的。这样做,是因为跨站请求可能会对目的站点的数据造成破坏。 当请求具备以下条件,就会执行预请求处理:
- 请求以GET,HEAD或者POST 以外的方法发起请求。或者,使用 POST,但contentType为
application/x-www-form-urlencoded<code style="margin: 0px 0px 24px; padding: 0px; border: 0px; font-style: inherit; font-weight: inherit; font-family: Consolas, Monaco, 'Andale Mono', monospace;">, multipart/form-data或者
text/plain
以外的数据类型。比如说,用 POST发送数据类型为application/json的JSON数据的请求。
- 使用自定义请求头
相关推荐
结束数据方法的参数,该如何定义?-- 集合为自定义实体类中的结合属性,有几个实体类,改变下标就行了。<input id="add" type="button" value="新增visitor&quo