如何解决跨域问题?

18801187951(338465)发表于:2022年12月02日 11:15:59更新于:2023年02月07日 14:28:18

一、什么是跨域

同源策略是浏览器一个重要的安全策略,所谓的同源就是指两个域有相同的协议(protocol)、域名(host)、端口(port),这三者之间任何一个不同都会构成跨域的情况,比如说前后端分离之后,前后都在两个域之下,前端的浏览器请求后端服务器的数据的时候就需要做跨域处理。

6aababdf8dc2365101fe1a43ec6a7a96.png

       更多参考:浏览器的同源策略
       https://developer.mozilla.org/zh-CN/docs/Web/Security/Same-origin_policy

二、跨域问题的判断依据

F12打开浏览器,查看控制台(Console) 的报错信息和网络请求(Network)状态(Status)

如果控制台有形如  …… has been blocked by CORS policy …… 的报错 或 网络请求状态有 CORS error 的报错,一般为跨域问题(报错截图如下)

4idA5QfVcW71aafb4d8af19GfI5w1B0uca6o4UbM8p5M8hcr899o30662K1adw2x.png?e=1669950771&token=PGtAPYyCYxCQ1zckbL-ecATOk42z8P3jdPahEnzt:juDVMmPePo7Zp6B9tf_GLTRRNHY=eD8k0Q17eYeueF2Sbz23194r3N6F852o2D3t3S9j0UdQe4dy2mfib5f22V73abeJ.png?e=1669950798&token=PGtAPYyCYxCQ1zckbL-ecATOk42z8P3jdPahEnzt:ArBISBGlrX-G5tBBTc6uL3YfZ2U=

三、如何解决跨域问题

使用 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下 

a145127b6b4de645f25586127adf7751.png

此时访问倾斜摄影的索引文件 tileset.json 是没问题的

fm3rem7P1j0f1qbE5U5ZaV5D6S4NeH6z8e5s646C3N6jbw098k1A3ufceB5U2Q6Q.png?e=1669714063&token=PGtAPYyCYxCQ1zckbL-ecATOk42z8P3jdPahEnzt:az9p5913H84j3wFbu7t_I3EVymA=

但在ThingJS在线开发加载倾斜摄影报错:

0d76055da85ca3e8d7f20092ddf46def.png

那么我们就需要对 Tomcat服务器进行相应的跨域配置,如下在Tomcat 相应的配置文件中,添加相应的 Filter(过滤器)配置项。

85278141e657d3fd602507ac37a3bd8c.png

正确配置重启Tomcat服务后即可正常加载倾斜摄影资源如下

5d802m6d1B76ax2j6q0GaQfUaL2KeHdfcW2z1raaah2H4UdS0d6m5vf07e8X2D5l.png?e=1669715010&token=PGtAPYyCYxCQ1zckbL-ecATOk42z8P3jdPahEnzt:m6s9EqpqJY8dju2lgZjL8h_RsCg=

 

以上


    您需要登录后才可以回复