【架构】Ajax跨域请求问题
一、什么是AJAX?
Asynchronous JavaScript and XML (Ajax ) 是驱动新一代 Web 站点(流行术语为 Web 2.0 站点)的关键技术。Ajax 允许在不干扰 Web 应用程序的显示和行为的情况下在后台进行数据检索。使用 XMLHttpRequest
函数获取数据,它是一种 API,允许客户端 JavaScript 通过 HTTP 连接到远程服务器。Ajax 也是许多 mashup 的驱动力,它可将来自多个地方的内容集成为单一 Web 应用程序。
二、为什么会有这个问题?
ajax本身实际上是通过XMLHttpRequest对象来进行数据的交互,而浏览器出于安全考虑,不允许js代码进行跨域操作,所以会警告。
三、常见解决办法
1、使用script标签
script调用没有域的限制,我们可以将输出的数据伪装成script的变量。
2、服务端脚本中转
服务端脚本使用XMLHTTP没有域的限制,但是耗费服务器的资源。
3、利用iframe
在同一个域名的各个子域名下,如果设置了document.domain,那么是可以相互调用JS的。
4、JSONP
这个方法也是最解决正常AJAX和多人使用的。
JSONP(JSON with Padding)是一个非官方的协议,它允许在服务器端集成Script tags返回至客户端,通过javascript callback的形式实现跨域访问(这仅仅是JSONP简单的实现形式)。
首先在客户端注册一个callback, 然后把callback的名字传给服务器。
此时,服务器先生成 json 数据。
然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp.
最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。
客户端浏览器,解析script标签,并执行返回的 javascript 文档,此时数据作为参数,传入到了客户端预先定义好的 callback 函数里.(动态执行回调函数)。
5、CORS
这也是我们这次采用的解决办法。
CORS-CrossOrigin Resources Sharing,也即跨源资源共享,它定义了一种浏览器和服务器交互的方式来确定是否允许跨域请求。它是一个妥协,有更大的灵活性,但比起简单地允许所有这些的要求来说更加安全。简言之,CORS就是为了让AJAX可以实现可控的跨域访问而生的。
但是CORS也具有一定的风险性,比如请求中只能说明来自于一个特定的域但不能验证是否可信,而且也容易被第三方入侵。
四、在jfinal中使用CORS
在jfinal中使用cors非常简单,这是得益于有cors的支持库。我们也将这个支持库上传到了我们的CDN服务器上
1、在开发项目中加入支持库
2、修改web.xml,增加以下代码
<filter>
<filter-name>CORS</filter-name>
<filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
<init-param>
<param-name>cors.allowOrigin</param-name>
<param-value>*</param-value>
</init-param>
<init-param>
<param-name>cors.supportedMethods</param-name>
<param-value>GET, POST, HEAD, PUT, DELETE</param-value>
</init-param>
<init-param>
<param-name>cors.supportedHeaders</param-name>
<param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
</init-param>
<init-param>
<param-name>cors.exposedHeaders</param-name>
<param-value>Set-Cookie</param-value>
</init-param>
<init-param>
<param-name>cors.supportsCredentials</param-name>
<param-value>true</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>CORS</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
注意cors的拦截需要在jfinal之前!
3、使用例子,我们这里用的是jQuery,其它框架类似。
$("#login").click(function() {
$.ajax("http://测试地址", {
type: "POST",
xhrFields: {
withCredentials: true,
useDefaultXhrHeader: false
},
data: {
username: "测试",
password: "测试"
},
crossDomain: true,
success: function(data, status, xhr) {
}
});
});
*** 转自:https://my.oschina.net/tbaby/blog/501333 ***