今天页面联调时出现了No 'Access-Control-Allow-Origin这样的问题,这个问题 当然有经验的老司机肯定可以看出来是跨域问题,这里对于这样的问题做一次总结。面试可能会被问到,前后分离存在什么问题,你可以回答说跨域的问题,如果你答上来了,可能会问你下一个问题,怎么解决?下面是我个人总结的。
解决方案1 jsonp
这种技术是在ajax里面进行声明,客户端的解决方案。
具体实现如下:
$(function($){
var url = 'http://xxxxxxx/index';
$.ajax(url, {
data: {
'cityname': '',
'date': '2016.12.12'
},
dataType: 'jsonp',
crossDomain: true,
success: function(data) {
if(data && data.resultcode == '200'){
console.log(data.result.today);
}
}
});
将ajax请求中的dataType属性设置为“jsonp”。
2.后台处理 spring针对跨域提供了注解 @CrossOrigin
1>Spring 4.2之后提供了跨域注解 @CrossOrigin;
2>可以用在方法或Controller上;
实现方式如下:
package com.arror.code_factory.controller;
import com.arror.code_factory.dao.DataBaseDAO;
import com.arror.code_factory.handler.GenerateTableSqlHandler;
import com.arror.code_factory.parm.SQLParam;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.util.List;
/**
* @Description
* @Author DJZ-WWS
* @Date 2019/5/30 11:26
*/
@RestController
@CrossOrigin
public class SQLController {
@Resource
private GenerateTableSqlHandler handler;
@Resource
private DataBaseDAO dataBaseDao;
@PostMapping("/createDaoPojoServiceImpl")
public String createDaoPojoServiceImpl(@RequestBody List sqlParam) {
//触发生成pojo
handler.handler(sqlParam);
return "ok";
}
@GetMapping("getDataBaseTables/{dataBaseName}")
public List getDataBaseTables(@PathVariable String dataBaseName){
//获取指定数据库的所有表信息
List tableList = dataBaseDao.listTables(dataBaseName);
return tableList;
}
}
3、使用Filter过滤处理器
一般的处理方法,在Filter中拦截请求,在请求头中添加信息,例如:
setHeader("Access-Control-Allow-Origin","*")
4.使用Nginx配置处理跨域(这种方式暂时没有做研究)
5.使用springmvc拦截器
在我们的实际项目使用是spring的注解还有就是Filter过滤器
代码如下:
public class CorsFilter implements Filter {
private String[] m_allowedOrigins = {"*"};
private String m_allowedMethods = "GET,POST,HEAD,OPTIONS,PUT,DELETE";
private List m_lstAllowedMethods = null;
private String m_allowedHeaders = "Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers";
private List m_lstAllowedHeaders = null;
private boolean m_supportCredentials = true;
private String m_preflightMaxAge = "1000";
@Override
public void init(FilterConfig config) throws ServletException {
String sAllowedOrigins = config.getInitParameter("cors.allowed.origins");
String sAllowedMethods = config.getInitParameter("cors.allowed.methods");
String sAllowedHeaders = config.getInitParameter("cors.allowed.headers");
String sSupportCredentials = config.getInitParameter("cors.support.credentials");
String sPreflightMaxAge = config.getInitParameter("cors.preflight.maxage");
if (sAllowedOrigins != null) {
m_allowedOrigins = sAllowedOrigins.toLowerCase().split("\\s*,\\s*");
}
if (sAllowedMethods != null) {
m_allowedMethods = sAllowedMethods;
m_lstAllowedMethods = Arrays.asList(m_allowedMethods.toLowerCase().split("\\s*,\\s*"));
}
if (sAllowedHeaders != null) {
m_allowedHeaders = sAllowedHeaders;
m_lstAllowedHeaders = Arrays.asList(m_allowedHeaders.toLowerCase().split("\\s*,\\s*"));
}
if (sSupportCredentials != null) {
m_supportCredentials = sSupportCredentials.equals("true");
}
if (sPreflightMaxAge != null) {
m_preflightMaxAge = sPreflightMaxAge;
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
String origin = req.getHeader("Origin");
if (origin != null) {
boolean matchFound = false;
for (String s : m_allowedOrigins) {
if (match(origin, s)) {
matchFound = true;
break;
}
}
if (!matchFound) {
chain.doFilter(req, res);
return;
}
if (req.getMethod() != null && req.getMethod().equals("OPTIONS")) {
String method = req.getHeader("Access-Control-Request-Method");
String strHeaders = req.getHeader("Access-Control-Request-Headers");
if (method == null) {
chain.doFilter(req, res);
return;
}
List headers = strHeaders == null ? new ArrayList() : Arrays.asList(strHeaders.split("\\s*,\\s*"));
if (!m_lstAllowedMethods.contains(method.toLowerCase())) {
chain.doFilter(req, res);
return;
}
for (String hdr : headers) {
if (!m_lstAllowedHeaders.contains(hdr.toLowerCase())) {
chain.doFilter(req, res);
return;
}
}
res.setHeader("Access-Control-Allow-Methods", m_allowedMethods);
res.setHeader("Access-Control-Allow-Headers", m_allowedHeaders);
res.setHeader("Access-Control-Max-Age", m_preflightMaxAge);
}
res.setHeader("Access-Control-Allow-Origin", origin);
if (m_supportCredentials) {
res.setHeader("Access-Control-Allow-Credentials", "true");
}
}
chain.doFilter(req, res);
}
@Override
public void destroy() {
}
private boolean match(String url, String pattern) {
return pattern.equals("*") || url.equals(pattern);
}
}
web.xml配置如下:
!--跨域访问过滤器-->
CorsFilter
com.gysoft.utils.cros.CorsFilter
cors.allowed.origins
*
cors.allowed.methods
GET,POST,HEAD,OPTIONS,PUT,DELETE
cors.allowed.headers
Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers
cors.support.credentials
true
cors.preflight.maxage
3600
CorsFilter
/*