跨站 HTTP 请求(Cross-site HTTP request)是指发起请求的资源所在域不同于该请求所指向资源所在的域的 HTTP 请求。
概念理解可参考此文章:跨源资源共享(CORS) - HTTP | MDN
一、更改Nginx反向代理服务器
原理大致是:通过nginx配置一个代理服务器做跳板机,反向代理后端接口
第一步:
先配置nginx.config,直接贴代码
server {
listen 8000;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
root E:/h5; #h5项目路径
}
location /urm { #代理的接口路径
proxy_pass http://192.168.1.111:9003/urm;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
add_header 'Access-Control-Allow-Origin' '*';
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
add_header 'Access-Control-Allow-Headers' 'DNT,X-CustomHeader,
Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
}
location = /favicon.ico {
log_not_found off;
access_log off;
}
}
第二步:启动后端服务器,启动nginx
二、更改项目配置
1、如果项目中使用的SpringMVC4.x以下,就需要对该请求配置Filter,设置请求头可支持跨域。
1、web.xml配置
<!-- 跨域问题解决 -->
<filter>
<filter-name>header</filter-name>
<filter-class>com.filter.HeaderFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>header</filter-name>
<url-pattern>/header/*</url-pattern>
</filter-mapping>
2、编写Filter拦截请求,添加跨域请求支持
package com.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 头部过滤器
* @author
*/
public class HeaderFilter implements Filter{
public void destroy() {
}
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest)req;
HttpServletResponse response = (HttpServletResponse) res;
String originHeader = request.getHeader("Origin");
response.setHeader("Access-Control-Allow-Origin", originHeader);
response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "0");
response.setHeader("Access-Control-Allow-Headers", "Origin, No-Cache, X-Requested-With, If-Modified-Since, Pragma, Last-Modified, Cache-Control, Expires, Content-Type, X-E4M-With,userId,token");
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("XDomainRequestAllowed","1");
response.setHeader("XDomainRequestAllowed","1");
chain.doFilter(request, response);
}
public void init(FilterConfig arg0) throws ServletException {
}
}
2、如果项目中使用的SpringMVC4.x以上常见的几种手段如下:
a. xml配置方式
<mvc:cors>
<mvc:mapping path="/ajax/*"
allowed-origins="/header/*"
max-age="3600" />
</mvc:cors>
b. 注解方式
在controller方法上,添加下面这个注解即可,也可以在类上注解
//在某个方法上注解
@RequestMapping("/crossDomain")
@ResponseBody
@CrossOrigin(origins="www.baidu.com" maxAge="3600")
public String crossDomain(HttpServletRequest req, HttpServletResponse res, String name){
……
……
}
//在类上注解
@Controller
@CrossOrigin
public class TestController {
……
……
}
@CrossOrigin中的2个参数:
origins : 允许可访问的域列表
maxAge:飞行前响应的缓存持续时间的最大年龄(以秒为单位)。
c. 直接修改返回的responseHeader
response.setHeader("Access-Control-Allow-Origin", request.getHeader("origin"));
response.setHeader("Access-Control-Allow-Methods", "*");
response.setHeader("Access-Control-Allow-Credentials", "true");
三、通过JSONP
可以参考Springmvc实现对jsonp的支持_Shemuel_Deng的博客-CSDN博客
小结:
如果是springMVC3.x的话 建议使用过滤器或者JSONP的方式,如果是springMVC4.x以上就直接注解即可。