Compartir tecnología

Comprender a fondo el dominio cruzado front-end

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

 

Tabla de contenido

1Política del mismo origen del navegador

1.1 Descripción general de la política del mismo origen

1.2 ¿Qué es el origen?

2. ¿Cuáles son las restricciones a las transacciones entre dominios?

2.1 Restringir el acceso DOM

2.2 Restringir el acceso a las cookies

2.3 Limitar Ajax para obtener datos

3 puntos a tener en cuenta

4CORS resuelve los problemas entre dominios de Ajax

4.1 Descripción general de CORS

4.2CORS resuelve solicitudes simples entre dominios

4.3 Solicitudes simples y solicitudes complejas

4.4CORS resuelve solicitudes complejas entre dominios

4.5 Utilice la biblioteca cors para completar rápidamente la configuración

5JSONP resuelve problemas entre dominios

6Configure el proxy para resolver problemas entre dominios

6.1 Configure usted mismo el servidor proxy

6.2 Utilice Nginx para crear un servidor proxy

6.3 Construir un servidor con la ayuda de andamios


Dirección de código git clone https://gitee.com/childe-jia/cross-domain-test.git

1Política del mismo origen del navegador

1.1 Descripción general de la política del mismo origen


La política del mismo origen es una política que siguen los navegadores para garantizar la seguridad de los recursos. Esta política impone algunas restricciones en el acceso a los recursos.
Descripción de la política del mismo origen del W3C:Política del mismo origen

1.2 ¿Qué es el origen?


1 componentes de origen

imagen.png


2En la siguiente tabla, solo las dos fuentes de la última fila tienen la misma fuente.

Fuente 1

Fuente 2

¿Es homólogo?

http://www.xyz.com/inicio

https://www.xyz.com/inicio

⛔No homogéneo️

http://www.xyz.com/inicio

http://mail.xyz.com/inicio

⛔No homogéneo

http://www.xyz.com:8080/inicio

http://www.xyz.com:8090/inicio

⛔No homogéneo

http://www.xyz.com:8080/inicio

http://www.xyz.com:8080/buscar

✅Mismo origen︎

 

3 solicitud de origen

imagen.png


4 Solicitud no original

imagen.png


5 Resumen: si la "fuente" es inconsistente con la "fuente de destino", significa "no fuente", también conocida como "heterofuente" o "dominio cruzado"

2. ¿Cuáles son las restricciones a las transacciones entre dominios?


Por ejemplo, si hay dos fuentes: "Fuente A" y "Fuente B", que son "no del mismo origen", entonces el navegador tendrá las siguientes restricciones:

2.1 Restringir el acceso DOM

El script de "Fuente A" no puede acceder al DOM de "Fuente B".

  1. <!-- <iframe id="framePage" src="./demo.html"></iframe> -->
  2. <iframe id="framePage" src="https://www.baidu.com"></iframe>
  3. <script type="text/javascript" >
  4. function showDOM(){
  5. const framePage = document.getElementById('framePage')
  6. console.log(framePage.contentWindow.document) //同源的可以获取,非同源的无法获取
  7. }
  8. </script>

2.2 Restringir el acceso a las cookies

La "Fuente A" no puede acceder a la cookie de la "Fuente B"

  1. <iframe id="baidu" src="http://www.baidu.com" width="500" height="300"></iframe>
  2. <script type="text/javascript" >
  3. // 访问的是当前源的cookie,并不是baidu的cookie
  4. console.log(document.cookie)
  5. </script>

2.3 Limitar Ajax para obtener datos

La "Fuente A" puede enviar solicitudes a la "Fuente B", pero no puede obtener los datos de respuesta de la "Fuente B".

  1. const url = 'https://www.toutiao.com/hot-event/hot-board/?origin=toutiao_pc'
  2. let result = await fetch(url)
  3. let data = await result.json();
  4. console.log(data)

Nota: Entre las restricciones anteriores, la restricción del navegador en la adquisición de datos Ajax tiene el mayor impacto y, a menudo, se encuentra en el desarrollo real.

3 puntos a tener en cuenta

  • 1Las restricciones entre dominios solo existen en el lado del navegador y no existen restricciones entre dominios en el lado del servidor.
  • 2 Incluso si es entre dominios, las solicitudes Ajax se pueden emitir normalmente, pero los datos de respuesta no se entregarán al desarrollador.
  • 3<link> , <script>、<img>...... 这些标签发出的请求也可能跨域,只不过浏览器对标签跨域不做严格限制,对开发几乎无影响

imagen.png

4CORS resuelve los problemas entre dominios de Ajax

4.1 Descripción general de CORS

El nombre completo de CORS: Cross-Origin Resource Sharing (Cross-Origin Resource Sharing) es un conjunto de especificaciones utilizadas para controlar la verificación del navegador de solicitudes entre dominios. El servidor sigue la especificación CORS y agrega encabezados de respuesta específicos para controlar la verificación del navegador. Las reglas generales son las siguientes:
●El servidor rechaza explícitamente las solicitudes entre dominios, o no lo indica, y el navegador falla la verificación.
●El servidor indica claramente que se permiten solicitudes entre dominios y la verificación del navegador pasa.
Nota: Usar CORS para resolver problemas entre dominios es la forma más ortodoxa y requiere que el servidor sea "propio".


4.2CORS resuelve solicitudes simples entre dominios

La idea general: cuando el servidor responde, expresa claramente que una determinada fuente puede iniciar solicitudes entre dominios agregando el encabezado de respuesta Access-Control-Allow-Origin, y luego el navegador lo pasa directamente durante la verificación.

imagen.png

Código central del lado del servidor (tome el marco expreso como ejemplo):

  1. // 处理跨域中间件
  2. function corsMiddleWare(req,res,next){
  3. // 允许 http://127.0.0.1:5500 这个源发起跨域请求
  4. // res.setHeader('Access-Control-Allow-Origin','http://127.0.0.1:5500')
  5. // 允许所有源发起跨域请求
  6. res.setHeader('Access-Control-Allow-Origin','*')
  7. next()
  8. }
  9. // 配置路由并使用中间件
  10. app.get('/',corsMiddleWare,(req,res)=>{
  11. res.send('hello!')
  12. })

4.3 Solicitudes simples y solicitudes complejas

CORS divide las solicitudes en dos categorías: ① solicitudes simples y ② solicitudes complejas.

petición sencilla

Solicitud compleja

✅El método de solicitud (método) es: GET, HEAD, POST

1 es una solicitud simple o una solicitud compleja.
2 Las solicitudes complejas enviarán automáticamente solicitudes de verificación previa.

✅Los campos del encabezado de la solicitud deben cumplir con"Especificación de seguridad CORS"
Nota breve: siempre que el encabezado de la solicitud no se modifique manualmente, generalmente puede cumplir con esta especificación.

✅El valor de tipo de contenido del encabezado de la solicitud solo puede ser los tres siguientes:
●texto/sin formato
● multipart/form-data
●application/x-www-form-urlencoded

Respecto a las solicitudes de verificación previa:

  • 1Tiempo de envío: la solicitud de verificación previa se envía antes de la solicitud entre dominios real y el navegador la inicia automáticamente.
  • 2 Función principal: se utiliza para confirmar con el servidor si se permite la siguiente solicitud entre dominios.
  • 3Proceso básico: primero inicie una solicitud de OPCIONES. Si pasa la verificación previa, continúe iniciando la solicitud entre dominios real.
  • 4 Contenido del encabezado de solicitud: una solicitud de verificación previa de OPCIONES generalmente contiene los siguientes encabezados de solicitud:

Encabezado de solicitud

significado

Origen

La fuente de la solicitud.

Método de solicitud de control de acceso

El método HTTP solicitado real

Encabezados de solicitud de control de acceso

Encabezados personalizados utilizados en la solicitud real (si corresponde)

4.4CORS resuelve solicitudes complejas entre dominios

1 Paso uno: el servidor primero pasa la solicitud de verificación previa del navegador. El servidor debe devolver el siguiente encabezado de respuesta:

encabezado de respuesta

significado

Control de acceso Permitir origen

fuentes permitidas

Métodos de permiso de control de acceso

métodos permitidos

Control de acceso: encabezados permitidos

Encabezados personalizados permitidos

Control de acceso Edad máxima

Tiempo de almacenamiento en caché de resultados para solicitudes de verificación previa (opcional)

imagen.png

2 Paso 2: Manejar la solicitud entre dominios real (de la misma manera que maneja solicitudes entre dominios simples)

imagen.png

Código central del servidor:

  1. // 处理预检请求
  2. app.options('/students', (req, res) => {
  3. // 设置允许的跨域请求源
  4. res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  5. // 设置允许的请求方法
  6. res.setHeader('Access-Control-Allow-Methods', 'GET')
  7. // 设置允许的请求头
  8. res.setHeader('Access-Control-Allow-Headers', 'school')
  9. // 设置预检请求的缓存时间(可选)
  10. res.setHeader('Access-Control-Max-Age', 7200)
  11. // 发送响应
  12. res.send()
  13. })
  14. // 处理实际请求
  15. app.get('/students', (req, res) => {
  16. // 设置允许的跨域请求源
  17. res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')
  18. // 随便设置一个自定义响应头
  19. res.setHeader('abc',123)
  20. // 设置允许暴露给客户端的响应头
  21. res.setHeader('Access-Control-Expose-Headers', 'abc')
  22. // 打印请求日志
  23. console.log('有人请求/students了')
  24. // 发送响应数据
  25. res.send(students)
  26. })

4.5 Utilice la biblioteca cors para completar rápidamente la configuración

En la configuración anterior, debe configurar el encabezado de respuesta usted mismo o encapsular manualmente el middleware. Con la biblioteca cors, puede completar la configuración de manera más conveniente.

●Instalar cors

npm i cors

●Cors de configuración simple

app.use(cors())

●Configurar completamente cors

  1. // cors中间件配置
  2. const corsOptions = {
  3. origin: 'http://127.0.0.1:5500', // 允许的源
  4. methods: ['GET', 'POST', 'PUT', 'DELETE', 'HEAD', 'OPTIONS'], // 允许的方法
  5. allowedHeaders: ['school'], // 允许的自定义头
  6. exposedHeaders: ['abc'], // 要暴露的响应头
  7. optionsSuccessStatus: 200 // 预检请求成功的状态码
  8. };
  9. app.use(cors(corsOptions)); // 使用cors中间件

De forma predeterminada, js no puede acceder al encabezado de respuesta establecido por el backend y debe ser expuesto por el backend.

5JSONP resuelve problemas entre dominios

Descripción general de 1JSONP: usos de JSONP<script>标签可以跨域加载脚本,且不受严格限制的特性,可以说是程序员智慧的结晶,早期一些浏览器不支持 CORS 的时,可以靠 JSONP 解决跨域。


2Proceso básico:

  • ○Paso uno: El cliente crea un<script>标签,并将其src属性设置为包含跨域请求的 URL,同时准备一个回调函数,这个回调函数用于处理返回的数据。
  • ○Paso 2: después de recibir la solicitud, el servidor encapsula los datos en la función de devolución de llamada y los devuelve.
  • ○Paso 3: se llama a la función de devolución de llamada del cliente y los datos se pasan a la función de devolución de llamada en forma de parámetros.

3Ilustración:

imagen.png

4 ejemplos de código:

  1. <button onclick="getTeachers()">获取数据</button>
  2. <script type="text/javascript" >
  3. function callback(data){
  4. console.log(data)
  5. }
  6. function getTeachers(url){
  7. // 创建script元素
  8. const script = document.createElement('script')
  9. // 指定script的src属性
  10. script.src= 'http://127.0.0.1:8081/teachers'
  11. // 将script元素添加到body中触发脚本加载
  12. document.body.appendChild(script)
  13. // script标签加载完毕后移除该标签
  14. script.onload = ()=>{
  15. script.remove()
  16. }
  17. }
  18. </script>

5jQuery jsonp encapsulado

?callback=?' es un formato fijo y se analizará automáticamente

  1. $.getJSON('http://127.0.0.1:8081/teachers?callback=?',(data)=>{
  2. console.log(data)
  3. })

6Configure el proxy para resolver problemas entre dominios

6.1 Configure usted mismo el servidor proxy

No hay problemas entre dominios entre servidores. Debe utilizar express para iniciar recursos estáticos para asegurarse de que su servidor y su página estén bajo el mismo origen.

  1. // 启动静态资源 让服务器跟页面同一个源
  2. app.use(express.static("./public"));

Configurar proxy con http-proxy-middleware

  1. const { createProxyMiddleware } = require('http-proxy-middleware');
  2. app.use('/api',createProxyMiddleware({
  3. target:'https://www.toutiao.com',
  4. changeOrigin:true,
  5. pathRewrite:{
  6. '^/api':''
  7. }

 

ventaja:

  • Funciones ricas: http-proxy-middleware proporciona una gran cantidad de opciones de configuración para satisfacer diversas necesidades de proxy.
  • Configuración flexible de múltiples servidores proxy: se pueden configurar múltiples servidores proxy, correspondientes a diferentes rutas de interfaz.
  • Puede interceptar solicitudes: las solicitudes se pueden interceptar y modificar mediante funciones de procesamiento personalizadas.

defecto:

  • La configuración es relativamente compleja: es necesario comprender las reglas y parámetros de configuración de la biblioteca http-proxy-middleware.
  • No apto para entornos de producción: http-proxy-middleware se utiliza principalmente en entornos de desarrollo y no es adecuado para entornos de producción.

escenas a utilizar:

  • Adecuado para proyectos front-end que utilizan cualquier herramienta de compilación y funciona con cualquier servidor de desarrollo.
  • Adecuado para escenarios en los que es necesario configurar de forma flexible varios servidores proxy.
  • Adecuado para escenarios en los que es necesario interceptar y modificar solicitudes.

6.2 Utilice Nginx para crear un servidor proxy

La idea general: dejar que nginx desempeñe dos funciones, como servidor de contenido estático y como servidor proxy.

Modifique la configuración de nginx de la siguiente manera. Tenga en cuenta que el directorio raíz de nginx no es preferiblemente la unidad C.

  1. # 配置nginx根目录
  2. location / {
  3. root D:dist;
  4. index index.html index.htm;
  5. }
  6. # 配置代理
  7. location /dev/ {
  8. # 设置代理目标
  9. proxy_pass http://sph-h5-api.atguigu.cn/;
  10. }

2 Modifique el proyecto front-end para que todas las solicitudes se reenvíen a /dev y luego se vuelvan a empaquetar

  1. const request = axios.create({
  2. baseURL:'/dev',
  3. timeout:10000
  4. })

Luego acceda directamente al servidor nginx. Por ejemplo, si nginx se está ejecutando en el puerto 8099, acceda.

http://localhost:8099

Luego encontrará el problema de actualización 404, agregue la configuración de nginx para resolverlo

  1. # 配置nginx根目录
  2. location / {
  3. root D:dist;
  4. index index.html index.htm;
  5. try_files $uri $uri/ /index.html; # 解决刷新404
  6. }
  7. # 配置代理
  8. location /dev/ {
  9. # 设置代理目标
  10. proxy_pass http://sph-h5-api.atguigu.cn/;
  11. }

Agregar estos dos "/" elimina dev

6.3 Construir un servidor con la ayuda de andamios

1. Utilice el archivo vue.config.js para configurar el proxy:

Cree un archivo vue.config.js en el directorio raíz del proyecto Vue y agregue el siguiente código:

  1. module.exports = {
  2. devServer: {
  3. proxy: {
  4. '/api': {
  5. target: 'http://api.example.com',
  6. changeOrigin: true,
  7. pathRewrite: {
  8. '^/api': ''
  9. }
  10. }
  11. }
  12. }
  13. }

En el código anterior, usamosdevServer Elementos de configuración para configurar el servidor proxy.enproxyLas propiedades se utilizan para configurar las reglas del proxy,/apiIndica la ruta de la interfaz que requiere proxy.targetEl atributo representa la dirección del servidor de destino del proxy,changeOriginEl atributo indica si se debe cambiar la dirección de origen de la solicitud.pathRewritePropiedad utilizada para anular la ruta solicitada.

ventaja:

  • Configuración simple: al utilizar la configuración de proxy de webpack-dev-server, solo necesita realizar una configuración simple en el archivo de configuración del paquete web.
  • Funcionalidad integral: webpack-dev-server proporciona una gran cantidad de opciones de configuración para satisfacer la mayoría de las necesidades de proxy.
  • Puede interceptar solicitudes: las solicitudes se pueden interceptar y modificar mediante funciones de procesamiento personalizadas.

defecto:

  • Es necesario reiniciar el servidor: después de modificar la configuración, es necesario reiniciar webpack-dev-server para que surta efecto.
  • No apto para entornos de producción: webpack-dev-server se utiliza principalmente en entornos de desarrollo y no es adecuado para entornos de producción.

escenas a utilizar:

  • Es adecuado para proyectos front-end creados con webpack e iniciando el servidor de desarrollo a través de webpack-dev-server.
  • Es adecuado para escenarios que requieren una configuración de proxy simple y no necesitan modificar la configuración del proxy con frecuencia.