搞懂什么是跨越?公司在开发中跨域的解决方案是什么?

news/2024/11/18 4:19:45/

文章目录

    • 什么是跨域?
    • 跨域的解决方案
      • 部署在同一服务器
      • CORS解决方案
      • 代理服务器
        • Node代理服务器
        • Nginx反向代理
    • 总结

什么是跨域?

要想理解跨域,要先理解浏览器的同源策略:

同源策略是浏览器中的一个重要的安全策略,它用于限制一个源(origin)的文档或者它加载的脚本如何能与另一个源的资源进行交互。它能帮助阻隔恶意文档,减少可能被攻击的媒介。

如果两个 URL的协议、主机、端口都相同的话,则这两个 URL 就是同源。

这个方案也被称为“协议/主机/端口元组”,或者直接是“元组”。

事实上跨域的产生和前端分离的发展有很大的关系:

在早期的服务器端渲染的阶段,是没有跨域的问题的;
但是随着前后端的分离,目前前端开发的代码和服务器开发的API接口往往是分离的,并且前端项目打包的静态资源和API接口甚至是部署在不同的服务器上的;

在这种情况下我们就会发现,访问静态资源服务器和API接口服务器 很有可能不是同一个服务器或者不是同一个端口。浏览器发现静态资源和API接口(XHR、Fetch)请求不是来自同一个地方时(不满足同源策略),这个时候就产生了跨域。

所以,在静态资源服务器和API服务器(其他资源类同)是同一台服务器时,是没有跨域问题的。

跨域的解决方案

其实跨域的解决方案几乎都和服务器有关系,单独的前端基本解决不了跨域(虽然网上也能看到各种方案可以让单独的前端解决跨域,但是实际开发基本不会使用, 所以我说基本解决不了跨域), 因此想要彻底搞懂跨域的问题还需掌握一些服务器端的知识。

有在webpack配置过跨域的同学可能就会有疑问, 我明明只需要在前端配置的webpack就可以解决跨域问题了, 那么为什么我还说单独的前端基本解决不了跨域呢?
其实在我们进行webpack配置是, 它的本质也是在webpack-server的服务器中配置了代理, 在我们进行了配置之后, webpack会开启一个node代理服务器, 并使用http-proxy-middleware插件, 将请求转发到真实请求的服务器中, node开启代理服务器具体的做法我会在下面讲到。

那么在开发中跨域的问题我们要如何解决呢?

网上有很多跨域解决方案的汇总, 多到九种、十种甚至更多, 但是很多跨域的解决方案都是我们开发中很少(几乎都不会使用的方案), 比如: jsonp、postMessage、websocket等等… 这些不常用甚至不用的方案我就不再过多赘述, 下面给大家介绍三种开发中最为常见的跨域解决方案

部署在同一服务器

我们只需要遵守浏览器的同源策略, 将静态资源服和API服务器部署到同一台服务器下自然就不会有跨域的问题

CORS解决方案

跨源资源共享 (CORS, Cross-Origin Resource Sharing跨域资源共享):

CORS(跨域资源共享), 它是http的header机制, 该机制通过允许服务器标识除了它自己以外的其它源(域、协议和端口),使得浏览器允许这些被标识的源(origin)访问加载自己的资源。

浏览器又将CORS请求分为两类: 简单请求和非简单请求

只要同时满足以下两大条件,就属于简单请求, 不满足就属于非简单请求(了解即可)。

条件一: 请求方法是以下是三种方法之一:

  • HEAD
  • GET
  • POST

条件二: HTTP 的头信息不超出以下几种字段:

  • Accept
  • Accept-Language
  • Content-Language
  • Last-Event-ID
  • Content-Type:只限于三个值 application/x-www-form-urlencoded、multipart/form-data、text/plain

如果只是简单请求, 我们只需要在服务器端进行以下配置即可(一般由后端开发进行配置):

"Access-Control-Allow-Origin", "*"

如果是非简单请求, 我们除上面之外, 还需要在服务器端进行以下配置:

"Access-Control-Allow-Origin", "*"
"Access-Control-Allow-Headers", "Accept, AcceptEncoding, Connection, Host, Origin"
"Access-Control-Allow-Credentials", true)
"Access-Control-Allow-Methods", "PUT, POST, GET, DELETE, PATCH, OPTIONS"
if (ctx.method === 'OPTIONS') {ctx.status = 204
} else {await next()
}

代理服务器

开发中常用代理服务器解决跨域方案有Node代理服务器和Nginx反向代理两种

Node代理服务器

Node代理服务器是平时开发中前端配置最多的一种方案, 像上面提到Webpack中进行代理配置, 就是采用的Node代理服务器。

实现思路

我们将原本发送请求的服务器, 改变为Node代理服务器, 再由代理服务器向原本请求的服务器发送请求, 由于同源策略是在浏览器端的, 所以代理服务器发送请求是没有同源策略的限制。但是这样一来,浏览器和Node代理服务器会存在跨域的问题,这个时候,我们通常的做法是将Node代理服务器和我们的静态资源部署在同一服务器下就不会产生跨域的问题。当然,也可以通过CORS的方式给Node代理服务器配置跨域。

例如我们向代理服务器发送请求:

fetch('http://localhost:9000/api/users/list')

代理服务器通过http-proxy-middleware插件, 在将请求转发到另一台服务器

const express = require('express')
const { createProxyMiddleware } = require('http-proxy-middleware')const app = express()app.use(express.static('./client'))app.use('/api', createProxyMiddleware({target: "http://localhost:8000",pathRewrite: {'^/api': ''}
}))app.listen(9000, () => {console.log('express proxy服务器开启成功')
})

Nginx反向代理

Nginx反向代理: 我们在向服务器发送请求时, 向Nginx服务器中进行发送, 再由Nginx服务器向原本的API服务器发送请求, 但是浏览器和Nginx服务器中存在跨域的问题, 我们需要在Nginx服务器中通过CORS进行跨域, 示例如下

location / {add_header Access-Control-Allow-Origin *;add_header Access-Control-Allow-Headers "Accept, AcceptEncoding, Connection, Host, Origin";add_header Access-Control-Allow-Credentials true;add_header Access-Control-Allow-Methods "PUT, POST, GET, DELETE, PATCH, OPTIONS";if ($method === 'OPTIONS') {return 204;}# 代理服务器请求的API服务器proxy_pass http://localhost:9000;
}

总结

那么在开发中上面跨域的解决方案我们该如何选择呢?

方案一: 如果是静态资源和API服务器部署在同一服务器下就不需要考虑跨域的问题, 但是实际开发中往往是分开部署的.

方案二: CORS是一种一劳永逸的解决方案, 我们只需要在服务器端进行一次配置, 就可以解决跨域的问题, 但是目前很多公司认为在这个方案在服务器端配置所有的源都可以进行访问, 是存在安全性问题的.

方案三: 代理服务器是目前使用最多的, 在开发阶段前端通过配置proxy开启一个Node代理服务器解决跨域; 在发布阶段, 我们在部署时会采用Nginx进行反向代理, 并且我们可以在Nginx中进行一些安全性的配置。


http://www.ppmy.cn/news/988168.html

相关文章

【JavaEE】博客系统前后端交互

目录 一、准备工作 二、数据库的表设计 三、封装JDBC数据库操作 1、创建数据表对应的实体类 2、封装增删改查操作 四、前后端交互逻辑的实现 1、博客列表页 1.1、展示博客列表 1.2、博客详情页 1.3、登录页面 1.4、强制要求用户登录,检查用户的登录状态 …

2、内核Kprobe的使用例子

#include <linux/kernel.h> #include <linux/module.h> #include <linux/kprobes.h>static int func_count 0;// 要跟踪的函数 static int example_function(int arg) {func_count;printk(KERN_INFO "Example function called with argument: %d\n&quo…

网络知识整理

网络知识整理 网络拓扑网关默认网关 数据传输拓扑结构层面协议层面 网络拓扑 网关 连接两个不同的网络的设备都可以叫网关设备&#xff0c;网关的作用就是实现两个网络之间进行通讯与控制。 网关设备可以是交换机(三层及以上才能跨网络) 、路由器、启用了路由协议的服务器、代…

意外:WPS编程新工具,不用编程,excel用户:可以不用VBA啦

来来来&#xff0c;拓宽一下视野&#xff01; 别总以为excel和WPS只能用VBA编程&#xff0c;也别总是想着ACCESS这些老生常谈的工具。其实对于电子表格高级用户来讲&#xff0c;不会VBA&#xff0c;不用ACCESS&#xff0c;也一样可以解决复杂问题或者高级应用。 尤其是WPS用户…

宝塔面板定时任务重启各种服务

一个php项目&#xff0c;laravel框架&#xff0c;使用了nginx php redis mysql 还有进程守护supervisor&#xff0c;用于laravel的异步队列进程queue&#xff0c;当服务器重启后有可能部分服务没有成功启动这个时候可以用定时任务去检查服务状态&#xff0c;然后对不正常的自动…

CVPR2023新作:pix2pix3D

Title: 3D-Aware Conditional Image SynthesisAffiliation: Carnegie Mellon University (卡内基梅隆大学)Authors: Kangle Deng, Gengshan Yang, Deva Ramanan, Jun-Yan ZhuKeywords: Image Synthesis, 3D-aware, Neural Radiance Fields, Interactive Editing, Conditional G…

ORA-19909与ORA-01110导致DG备库应用停止

ORA-19909与ORA-01110导致DG备库应用停止 现象分析问题处理 现象分析 DG备库MRP日志应用进程停止&#xff0c;重启进程后马上又会挂掉。 检查告警日志中的相关告警信息&#xff0c;注意到错误ORA-19909和ORA-1110&#xff1a; [oracleoraclehost ~]$ tail -n 2000 $ORACLE_B…

Ubuntu Server版 之 apache系列 安装、重启、开启,版本查看

安装之前首先要检测是否安装过 apt list --installed | grep tool tool&#xff1a;要检测的名称&#xff0c;如mysql、apache 、ngnix 等 安装 apache sudo apt install apache2 安装apache 默认是开启的 可以通过浏览器 检测一下 service apache stop # apache 停止服务…