ajax跨域的原理:
ajax出现请求跨域错误问题,主要原因就是因为浏览器的“同源策略”,“同源”是指协议相同、域名相同和端口相同。同源的策略是为了保证用户的信息安全防止网站的恶意窃取用户的数据信息等。
CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest
请求,从而克服了AJAX只能同源使用的限制。
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
HTTP的头信息不超出以下几种字段:
凡是不同时满足上面两个条件,就属于非简单请求。
解决方法:
jsonp解决跨域问题是一个比较古老的方案(实际中不推荐使用),这里做简单介绍(实际项目中如果要使用JSONP,一般会使用JQ等对JSONP进行了封装的类库来进行ajax请求)
CORS的原理上文中已经介绍了,这里主要介绍的是,实际项目中,后端应该如何配置以解决问题(因为大量项目实践都是由后端进行解决的),这里整理了一些常见的后端解决方案:
PHP后台配置
PHP后台得配置几乎是所有后台中最为简单的,遵循如下步骤即可:
原始代码
AllowOverride none
Require all denied
改为以下代码
Options FollowSymLinks
AllowOverride none
Order deny,allow
Allow from all
Node.js后台配置(express框架)
Node.js的后台也相对来说比较简单就可以进行配置。只需用express如下配置:
app.all('*', function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "X-Requested-With");
res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
res.header("X-Powered-By", ' 3.2.1')
//这段仅仅为了方便返回json而已
res.header("Content-Type", "application/json;charset=utf-8");
if(req.method == 'OPTIONS') {
//让options请求快速返回
res.sendStatus(200);
} else {
next();
}
});
JAVA后台配置
JAVA后台配置只需要遵循如下步骤即可:
下载 cors-filter-1.7.jar, java-property-utils-1.9.jar 这两个库文件放到lib目录下。(放到对应项目的webcontent/WEB-INF/lib/下)
com.thetransactioncompany
cors-filter
[ version ]
其中版本应该是最新的稳定版本,CORS过滤器
CORS
com.thetransactioncompany.cors.CORSFilter
cors.allowGenericHttpRequests
true
cors.allowOrigin
*
cors.allowSubdomains
false
cors.supportedMethods
GET, HEAD, POST, OPTIONS
cors.supportedHeaders
Accept, Origin, X-Requested-With, Content-Type, Last-Modified
cors.exposedHeaders
X-Test-1, X-Test-2
cors.supportsCredentials
true
cors.maxAge
3600
CORS
/*
请注意,以上配置文件请放到web.xml的前面,作为第一个filter存在(可以有多个filter的)
JAVA Spring Boot配置
20171230补充
仅列举简单的全局配置
@Configuration
public class CorsConfig {
private CorsConfiguration buildConfig() {
CorsConfiguration corsConfiguration = new CorsConfiguration();
// 可以自行筛选
corsConfiguration.addAllowedOrigin("*");
corsConfiguration.addAllowedHeader("*");
corsConfiguration.addAllowedMethod("*");
return corsConfiguration;
}
@Bean
public CorsFilter corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
source.registerCorsConfiguration("/**", buildConfig());
return new CorsFilter(source);
}
}
新建配置,然后添加Configuration注解即可配置成功
PS:这一部分方法是收录的,没有亲身实践过,但根据反馈,理论上可行
NET后台配置
.NET后台配置可以参考如下步骤:
打开控制面板,选择管理工具,选择iis;右键单击自己的网站,选择浏览;打开网站所在目录,用记事本打开web.config文件添加下述配置信息,重启网站
请注意,以上截图较老,如果配置仍然出问题,可以考虑增加更多的headers允许,比如:
"Access-Control-Allow-Headers":"X-Requested-With,Content-Type,Accept,Origin"
第二步:其它更多配置,如果第一步进行了后,仍然有跨域问题,可能是:
Origin:*
,请去除即可Origin:*
,请去除即可注意,由于接口代理是有代价的,所以这个仅是开发过程中进行的。
与前面的方法不同,前面CORS是后端解决,而这个主要是前端对接口进行代理,也就是: