跨域问题有前台跨域(iframe间)和后台跨域。
前台跨域的解决方案可以采用跨域文档通讯(Cross domain message)
详细见: http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html
后台跨域解决方案采用跨域资源共享(CORS:Cross-origin resource sharing)
理论方面详见阮老师的博客:http://www.ruanyifeng.com/blog/2016/04/cors.html
Java 后台处理CORS代码示例:
package filters;
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.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* Servlet Filter implementation class CORSFilter
*/
@WebFilter("/*")
public class CORSFilter implements Filter {
/**
* Default constructor.
*/
public CORSFilter() {
// TODO Auto-generated constructor stub
}
/**
* @see Filter#destroy()
*/
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletResponse response = (HttpServletResponse) servletResponse;
// HttpServletRequest request = (HttpServletRequest) servletRequest;
// 指定允许其他域名访问
response.setHeader("Access-Control-Allow-Origin", "*");
// 响应类型
response.setHeader("Access-Control-Allow-Methods", "POST, GET, DELETE, OPTIONS, DELETE");
// 响应头设置
response.setHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with, X-Custom-Header, HaiYi-Access-Token");
// if ("OPTIONS".equals(request.getMethod())){
// // response.setStatus(HttpStatus.SC_NO_CONTENT);
// }
filterChain.doFilter(servletRequest, servletResponse);
}
/**
* @see Filter#init(FilterConfig)
*/
public void init(FilterConfig fConfig) throws ServletException {
// TODO Auto-generated method stub
}
}
NodeJS CORS 处理代码
//创建一个服务
var httpServer = http.createServer(processRequest);
//在指定的端口监听服务
httpServer.listen(port,function(){
console.log("[HttpServer][Start]","runing at http://"+ip+":"+port+"/");
console.timeEnd("[HttpServer][Start]");
});
httpServer.on("error", function(error) {
console.error(error);
});
/**
* 请求处理
* @param request
* @param response
*/
function processRequest(request,response){
var requestUrl = request.url;
var pathName = url.parse(requestUrl).pathname;
//对请求的路径进行解码,防止中文乱码
pathName = decodeURI(pathName);
//获取资源文件的相对路径
var filePath = "public" + pathName;
filePath = path.join(projectPath, filePath);
//获取对应文件的文档类型
var contentType = getContentType(filePath);
console.log(contentType);
console.log(filePath);
response.setHeader("content-type", contentType);
response.setHeader('Access-Control-Allow-Origin', '*');
response.setHeader('Access-Control-Allow-Credentials', true);
//如果文件名存在
fs.access(filePath, function(err){
if(!err){
fs.readFile(filePath, 'utf-8', function(err, bytes){
//读取失败
if(err){
response.write(getErrorJson(`读取${pathName}文件失败!`));
response.end();
throw new Error("读取文件失败");
}
//返回文件内容
var data = JSON.parse(bytes);
response.write(JSON.stringify(data));
response.end();
});
}else { //文件名不存在的情况
response.write(JSON.stringify(getErrorJson(`${pathName}文件不存在!`)));
response.end();
}
});
}