一、什么是跨域
同源策略是浏览器一个重要的安全策略,所谓的同源就是指两个域有相同的协议(protocol)、域名(host)、端口(port),这三者之间任何一个不同都会构成跨域的情况,比如说前后端分离之后,前后都在两个域之下,前端的浏览器请求后端服务器的数据的时候就需要做跨域处理。
更多参考:浏览器的同源策略
https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy
二、跨域问题的判断依据
F12打开浏览器,查看控制台(Console) 的报错信息和网络请求(Network)状态(Status)
如果控制台有形如 …… has been blocked by CORS policy …… 的报错 或 网络请求状态有 CORS error 的报错,一般为跨域问题(报错截图如下)
三、如何解决跨域问题
使用 CORS 来允许跨源访问
在服务端程序或配置中根据实际情况,添加以下响应头,来支持 CORS:
Access-Control-Allow-Origin
Access-Control-Allow-Methods
Access-Control-Allow-Headers
等
更多参考:跨源资源共享(CORS)
https://developer.mozilla.org/zh-CN/docs/Web/HTTP/CORS
①用户后端服务接口代码自行实现
不同的编程语言(Java、PHP、NodeJS)、不同的框架可能相应的代码或设置方式也不同,后端开发人员根据实际开发语言配置即可。
下面仅举两例示意说明,并不代表最终用户实际代码实现:
例1:node 代码中添加响应头
app.use(function(req,res,next){ res.header("Access-Control-Allow-Origin", "*"); res.header('Access-Control-Allow-Methods', 'PUT, GET, POST, DELETE, OPTIONS'); res.header("Access-Control-Allow-Headers", "X-Requested-With"); res.header('Access-Control-Allow-Headers', 'Content-Type'); next(); });
例2:Java Filter过滤器中添加响应头
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.HttpServletResponse; @WebFilter(filterName= "CorsFilter", urlPatterns="*.do") public class CorsFilter implements Filter{ @Override public void destroy() { } @Override public void doFilter(ServletRequest req, ServletResponse resp, FilterChain chain) throws IOException, ServletException { HttpServletResponse response = (HttpServletResponse) resp; //解决跨域访问报错 response.setHeader("Access-Control-Allow-Origin", "*"); chain.doFilter(req, resp); } @Override public void init(FilterConfig arg0) throws ServletException { } }
②通过nginx配置nginx.conf解决
有时候在浏览器访问应用程序时,中间会有nginx作为代理转发浏览器的请求,此时我们就需要在nginx端解决跨域访问的问题。
只需要在Nginx的配置文件中配置以下参数:
location /thing { if ($request_method = 'OPTIONS') { add_header Access-Control-Allow-Origin * always; add_header Access-Control-Allow-Methods 'GET,POST,PUT,DELETE,OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; return 200; } add_header Access-Control-Allow-Origin '*' always; add_header Access-Control-Allow-Methods 'GET, PUT, POST, DELETE, OPTIONS'; add_header Access-Control-Allow-Headers 'DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; proxy_pass http://ip:port/thing; }
③用户Web服务器自行配置
有时候客户的一些静态资源也可能通过他们自己的Web服务器发布(比如Tomcat、Apache、Nginx 甚至 Window的IIS 或者其他),那么在访问这些静态资源时也可能涉及跨域。
比如把倾斜摄影的数据放到了 Tomcat下
此时访问倾斜摄影的索引文件 tileset.json 是没问题的
但在ThingJS在线开发加载倾斜摄影报错:
那么我们就需要对 Tomcat服务器进行相应的跨域配置,如下在Tomcat 相应的配置文件中,添加相应的 Filter(过滤器)配置项。
正确配置重启Tomcat服务后即可正常加载倾斜摄影资源如下
以上