Tomato 的个人博客

记录精彩的程序人生

Open Source, Open Mind,
Open Sight, Open Future!
  menu
8 文章
0 浏览
1 当前访客
ღゝ◡╹)ノ❤️

跨域解决方案

一、Nginx

关于Nginx的用途,听到最多的两个词,就是:

  • 端口转发
  • 负载均衡

负载均衡不属于现阶段要学习的内容,重点来看一看端口转发,本文用它来解决跨域请求的问题。

二、CROS 跨域资源共享

我们需要知道,同源的三要素:协议域名端口
如果比较两个地址 ,只要三者中只要有任何一个 不同,就算跨域。

// 协议:http
// 域名:localhost
// 端口:8011

http://localhost:8011

出于安全原因,浏览器限制从脚本(比如JavaScript)内发起的跨源HTTP请求。
如果浏览器检测到跨域,它会尝试发起一次请求,然后查看返回的内容中,是否一个有允许跨域请求的标记 (CORS响应头),如果有正确的标记 ,那么就不拦截;如果没有标记,浏览器就会阻止这个请求。并报错。
1716795022323.png

三、项目中为何产生跨域

前后台分离 的项目中,前台和后台分别运行在不同的端口上。

1716795171818.png

所以前台后台 发起请求时,会因为跨域,而被浏览器拦截下来。

1716795245920.png

浏览器错误信息:
1716795296025.png

这时解决方案有两个:

  • 开放跨域请求
  • 使跨域变成同源

第一种方法,显然不安全 ,开放跨域意味着,浏览器不再进行拦截。如果前台代码被篡改,把后台的地址指向黑客的服务器,那么会对用户造成损失。

第二种方法,想办法变成同一个域,这就轮到Nginx出场了!

四、使用Nginx转发

首先要明白,是谁把前台向后台的请求拦截下来的?不是后台 ,而是浏览器
如果要避免跨域,只要让浏览器认为 “我正在向同一个域发起请求”,就可以了。

假设前台使用4200端口,后台使用8080端口,那么,再加入一个8011端口,作为用户访问时连接的端口。
在前台的代码中,会有拦截器,如果发现某个请求是指向后台 的,就会在Url中加入一个特殊的标识(比如加一个**/api/** 作为前缀)

// header中带有do_not_intercept,且值为true,则不添加url前缀
if (('true' !== req.headers.get(YunzhiInterceptor.DONT_INTERCEPT_HEADER_KEY))
  && !url.startsWith('https://') && !url.startsWith('http://')) {
  url = '/api/' + url;
}

现在,无论是指向前台还是后台的请求,都会发送到8011端口,只不过,指向后台的请求会有一个**/api/** 前缀。

接下来使用Nginx监听8011 端口,当接收到请求时,根据是否有前缀,来判断此请求交给前台或后台处理。

过程如图:
1716795323304.png

上图就是转发的原理。

五、总结

使用Nginx端口转发,本质上就是:让浏览器认为前台和后台是同一个域,就不会产生跨域请求。
开发者事先约定好,根据不同的请求地址,来访问不同的服务器。
Nginx接收到数据之后,根据地址,转发给相应的服务器来处理。
如果需要另外安排其他的服务,来实现文件上传功能的话,只需要把URL处理一下,加上不同的前缀即可。

转载来源:Nginx解决跨域请求,通俗解释 - 个人文章 - SegmentFault 思否


标题:跨域解决方案
作者:MrTomato
地址:https://isee-you.icu/articles/2024/05/27/1716794955399.html