跨域是什么?前端跨域的解决办法?

221 阅读4分钟

跨域作为面试题中的老生常谈,作为一个前端去了解是很有必要的。

最近在面试的时候就频繁被问到,之前没有解决经验被问到真的是一头蒙。(呜呜呜呜,,难过难过,,这就是面试不背面试题的下场(T_T))

今天我们就争取一篇文章把跨域讲清楚!!!


什么是跨域

跨域资源共享(英语:Cross-origin resource sharing,缩写:CORS),用于让网页的受限资源能够被其他域名的页面访问的一种机制。

说人话:让一个网页访问不同源的另一个网页的信息。

浏览器是默认阻止网页向另一个不同源的链接发送请求的,这是为了浏览器的安全考虑,如果允许访问的话用户的cookie和token等内容都会被暴露,很不安全。

什么是同源

同源讲的是url中 协议,域名,端口号 相同

url的结构:

  • protocol:协议 http/https

  • host:主机地址IP/域名

    • ip:任意一台电脑主机都有自己的标识,ipv4/ipv6,ipv4现在用完了几乎(不好记忆)

    • 域名:ip地址的美化,方便人们记忆,通过域名访问主机地址,需要通过DNS解析后找到真正的IP

    • 服务器名:主机上一个域名可能有不同的功能分区,所以有时在域名前面加上服务器名的前缀服务器名(www.music.)+主域(qq.com/XXX)

  • port : 端口号。指主机上分享的窗口,可以想象成房子上的窗口,用于不同主机之间上通信。http默认打开80端口,https默认打开443端口

  • path:访问主机内容的路径

  • query:查询参数。写法: ?name=value&&name=value 。以问号?起始,以name=value的形式向后拼接,不同参数之间&&连接

  • fragment:片段--锚点下面a标签点击后网址中出现的片段,以警号开头#aaa

怎么解决跨域

jsonp解决跨域

jsonp利用在script标签没有跨域的特性,来解决跨域。

具体流程:

  1. 前端写一个和后端规定好的回调函数来接收请求内容(例如onResponse函数)
  2. 后端响应请求,并把响应内容写到规定的函数字符串内传给前端(例如res.end(onResponse(${JSON.stringify(posts)}));
  3. 前端执行对应函数,收到结果

缺点:只能执行get请求,因为script只能接收get请求

cors后端解决跨域

后端解决跨域的思路是:让后端在响应的时候加上对应的响应头,信任相应域名,即可解决跨域。请求分为简单请求和复杂请求,需要配置不同的请求头

  • 对于简单请求,乙站点在响应头里添加 Access-Control-Allow-Origin: http://甲站点 即可
  • 对于复杂请求,如 PATCH,乙站点需要:
    • 响应 OPTIONS 请求,在响应中添加如下的响应头
    Access-Control-Allow-Origin: https://甲站点 
    Access-Control-Allow-Methods: POST, GET, OPTIONS, PATCH 
    Access-Control-Allow-Headers: Content-Type
    
    • 响应 POST 请求,在响应中添加 Access-Control-Allow-Origin 头。
    • 如果需要附带身份信息,JS 中需要在 AJAX 里设置 xhr.withCredentials = true 。

代理解决跨域

代理分为正向代理和反向代理,正向代理由客户端配置,反向代理由服务端配置。 对于我们这种情况一般使用正向代理。

代理的分类

正向代理

正向代理是位于客户端和目标服务端之间的服务器。客户端向正向代理服务器发送消息,正向代理把我们的消息发送给目标服务器。

用途:正向代理通常用于隐藏客户端的真实身份,绕过防火墙,如VPM。

graph LR
客户端 --> 正向代理服务器 --> 目标服务器

反向代理

反向代理是位于服务器和客户端之间的服务器。客户端向反向代理发送请求,反向代理将请求路由发送到一个或者多个目标服务器上。客户端不知道响应来自哪台服务器。

用途:

负载均衡,安全性和简化客户端请求

graph LR
客户端 --> 正向代理服务器 --> 目标服务器1 & 目标服务器2 & 目标服务器3

vite配置正向代理

vite在本地起一个服务配置正向代理,帮助我们解决跨域。

比如说localhost:3000端口要获取localhost:80的内容

graph LR
 3000端口发送请求--> vite代理接收转发 --> 80端口接收

配置例子,配置在vue.config.js内

export default defineConfig({
  plugins: [react()],
  server: {
    port: 3000,    //自定义启动时的端口
    proxy: {
      "/api/1": {
        target: "http://localhost:80",
        //你的需要请求的服务器地址
        changeOrigin: true, // 允许跨域
        rewrite: (path) => path.replace(/^\/api^\/1/, ''), // 重写路径把路径变成空字符,
      },
    },
  }
})


这大概就是配置跨域的思路啦~希望每个小伙伴看完都能会配跨域!把跨域讲清楚!

我是发面糕!我们下节再见!(❁´◡`❁)