当前位置: 首页 > article >正文

大白话跨域问题怎么破,解决方法有啥?

大白话跨域问题怎么破,解决方法有啥?

啥是跨域问题

咱先说说啥是跨域。你可以把每个网站想象成一个独立的小房子,每个房子都有自己的地址(也就是域名)。正常情况下,一个房子里的东西只能在这个房子里用,不能随便跑到别的房子里去。在网页开发里,浏览器有个“同源策略”,就像规定了房子和房子之间不能随便串门。如果一个网页要从它所在的域名去访问另一个域名下的资源,这就相当于要从一个房子跑到另一个房子去拿东西,浏览器就会阻止这种行为,这就是跨域问题。比如说,你在 http://www.example1.com 这个网站的页面里,想访问 http://www.example2.com 网站的接口数据,就会遇到跨域问题。

解决方法

1. JSONP(JSON with Padding)
  • 原理:JSONP 利用了 <script> 标签的 src 属性不受同源策略限制的特点。就好比 <script> 标签有个特殊通行证,可以去别的房子拿东西。服务器返回的数据会被包裹在一个回调函数里,网页通过 <script> 标签请求这个带有回调函数的脚本,拿到数据后就可以在回调函数里处理。
  • 代码示例
    • 服务器端(Node.js + Express)
const express = require('express');
const app = express();

app.get('/data', (req, res) => {
    const callback = req.query.callback;
    const data = { message: '这是从服务器返回的数据' };
    const jsonp = `${callback}(${JSON.stringify(data)})`;
    res.send(jsonp);
});

const port = 3000;
app.listen(port, () => {
    console.log(`服务器运行在端口 ${port}`);
});
- **客户端(HTML + JavaScript)**
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
</head>

<body>
    <script>
        function handleData(data) {
            console.log(data.message);
        }
        const script = document.createElement('script');
        script.src = 'http://localhost:3000/data?callback=handleData';
        document.body.appendChild(script);
    </script>
</body>

</html>
  • 优缺点
    • 优点:兼容性好,几乎所有浏览器都支持。
    • 缺点:只支持 GET 请求,安全性较低,容易受到 XSS 攻击。
2. CORS(Cross - Origin Resource Sharing,跨域资源共享)
  • 原理:CORS 是一种现代的跨域解决方案,它是服务器端的一种机制。服务器通过设置响应头,告诉浏览器哪些域名可以访问它的资源,浏览器看到这些响应头后,就会允许跨域请求。就好比房子的主人给某些房子发了邀请函,拿到邀请函的房子里的人就可以来串门了。
  • 代码示例
    • 服务器端(Node.js + Express)
const express = require('express');
const app = express();

// 设置 CORS 响应头
app.use((req, res, next) => {
    res.setHeader('Access - Control - Allow - Origin', '*'); // 允许所有域名访问
    res.setHeader('Access - Control - Allow - Methods', 'GET, POST, PUT, DELETE');
    res.setHeader('Access - Control - Allow - Headers', 'Content - Type');
    next();
});

app.get('/data', (req, res) => {
    const data = { message: '这是从服务器返回的数据' };
    res.json(data);
});

const port = 3000;
app.listen(port, () => {
    console.log(`服务器运行在端口 ${port}`);
});

客户端(HTML + JavaScript)

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
</head>

<body>
    <script>
        fetch('http://localhost:3000/data')
          .then(response => response.json())
          .then(data => console.log(data.message));
    </script>
</body>

</html>
  • 优缺点
    • 优点:支持各种 HTTP 请求方法(GET、POST 等),安全性高。
    • 缺点:需要服务器端进行配置,对于一些老旧服务器可能不支持。
3. 代理服务器
  • 原理:代理服务器就像一个中间人。客户端把请求发给代理服务器,代理服务器再把请求转发给目标服务器,拿到目标服务器的响应后,再把响应返回给客户端。因为代理服务器和客户端在同一个域名下,所以不存在跨域问题。就好比你想从另一个房子拿东西,你把请求告诉一个住在你家附近的朋友,这个朋友去帮你从那个房子里把东西拿回来给你。
  • 代码示例(开发环境下使用 Webpack 代理)
    • Webpack 配置文件
const path = require('path');
const webpack = require('webpack');
const { WebpackDevServer } = require('webpack - dev - server');

const config = {
    // 其他配置...
    devServer: {
        proxy: {
            '/api': {
                target: 'http://localhost:3000', // 目标服务器地址
                changeOrigin: true,
                pathRewrite: { '^/api': '' }
            }
        }
    }
};

const compiler = webpack(config);
const server = new WebpackDevServer(compiler, config.devServer);
server.listen(8080, 'localhost', () => {
    console.log('开发服务器运行在端口 8080');
});
- **客户端(HTML + JavaScript)**
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF - 8">
</head>

<body>
    <script>
        fetch('/api/data')
          .then(response => response.json())
          .then(data => console.log(data.message));
    </script>
</body>

</html>
  • 优缺点
    • 优点:不需要服务器端进行额外配置,适合开发环境。
    • 缺点:需要搭建代理服务器,增加了系统复杂度。

啥是跨域问题

咱先把跨域问题说明白。你可以把每个网站想象成不同的小区,每个小区都有自己的门禁系统(也就是浏览器的同源策略)。同源策略规定,只有同一个小区(也就是域名、端口、协议都相同)里的住户(页面资源)才能自由交流。要是一个小区的住户想和另一个小区的住户通信,就会被门禁拦住,这就是跨域问题。在前端开发里,当你用 React 或者 Vue 3 写的页面想去请求另一个域名下的接口数据时,就会遇到这种情况。

React 框架跨域问题及解决办法

开发环境下用代理服务器解决
  • 原理:在开发的时候,就好比你请了一个跑腿小哥。你把请求交给这个小哥,小哥拿着你的请求去另一个小区(目标服务器)帮你办事,然后把结果带回来给你。因为小哥是你们小区(本地开发服务器)的人,所以能顺利进出,这样就绕过了门禁(同源策略)。
  • 操作步骤
    • 如果你用 create - react - app 创建的项目,在 package.json 文件里加一行配置。比如目标服务器地址是 http://api.example.com ,就在 package.json 里加上 "proxy": "http://api.example.com" 。这就相当于告诉跑腿小哥他要去的地方。
    • 在 React 代码里发请求。比如你要请求 http://api.example.com/api/data 这个接口,代码里就写 fetch('/api/data') 。因为有了前面的配置,开发服务器会自动把这个请求转发到目标服务器。
import React, { useEffect } from'react';

function App() {
    useEffect(() => {
        async function getData() {
            try {
                const response = await fetch('/api/data');
                const data = await response.json();
                console.log(data);
            } catch (error) {
                console.error('请求出错啦:', error);
            }
        }
        getData();
    }, []);

    return (
        <div>
            <h1>React 跨域请求示例</h1>
        </div>
    );
}

export default App;
生产环境用 CORS 解决
  • 原理:到了正式上线的生产环境,就不能用跑腿小哥了。这时候得让另一个小区(目标服务器)的门卫(服务器)给你发个通行证。服务器通过设置一些特殊的响应头,告诉浏览器你的小区(域名)可以访问它的资源。
  • 操作步骤
    • 服务器端设置。假设目标服务器用 Node.js 和 Express 搭建,在代码里加上下面这些设置:
const express = require('express');
const app = express();

// 设置允许访问的域名
app.use((req, res, next) => {
    res.setHeader('Access - Control - Allow - Origin', 'http://your - react - app.com'); 
    res.setHeader('Access - Control - Allow - Methods', 'GET, POST, PUT, DELETE');
    res.setHeader('Access - Control - Allow - Headers', 'Content - Type');
    next();
});

app.get('/api/data', (req, res) => {
    const data = { message: '这是服务器返回的数据' };
    res.json(data);
});

const port = 3000;
app.listen(port, () => {
    console.log('服务器在端口 3000 运行');
});
- 在 React 代码里正常发请求就行。
import React, { useEffect } from'react';

function App() {
    useEffect(() => {
        async function getData() {
            try {
                const response = await fetch('http://api.example.com/api/data');
                const data = await response.json();
                console.log(data);
            } catch (error) {
                console.error('请求出错啦:', error);
            }
        }
        getData();
    }, []);

    return (
        <div>
            <h1>React 跨域请求示例</h1>
        </div>
    );
}

export default App;

Vue 3 框架跨域问题及解决办法

开发环境用代理服务器解决
  • 原理:和 React 开发环境一样,也是请个跑腿小哥。Vue 3 一般用 Vue CLI 来开发,Vue CLI 的开发服务器能充当这个跑腿小哥。
  • 操作步骤
    • vue.config.js 文件里配置代理。比如目标服务器是 http://api.example.com ,文件内容可以这样写:
module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://api.example.com',
                changeOrigin: true,
                pathRewrite: { '^/api': '' }
            }
        }
    }
};
这里的 `/api` 是你本地请求的前缀,`target` 是目标服务器地址,`changeOrigin` 表示是否改变请求的源,`pathRewrite` 是对请求路径进行重写。
- 在 Vue 3 组件里发请求。
<template>
    <div>
        <h1>Vue 3 跨域请求示例</h1>
    </div>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(async () => {
    try {
        const response = await fetch('/api/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('请求出错啦:', error);
    }
});
</script>
生产环境用 CORS 解决
  • 原理:同样是让目标服务器的门卫发通行证。
  • 操作步骤
    • 服务器端设置和前面 React 生产环境的服务器设置一样。
    • 在 Vue 3 组件里正常发请求。
<template>
    <div>
        <h1>Vue 3 跨域请求示例</h1>
    </div>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(async () => {
    try {
        const response = await fetch('http://api.example.com/api/data');
        const data = await response.json();
        console.log(data);
    } catch (error) {
        console.error('请求出错啦:', error);
    }
});
</script>

http://www.kler.cn/a/568835.html

相关文章:

  • 行为型模式 - 迭代器模式 (Iterator Pattern)
  • 蓝桥备赛(六)- C/C++输入输出
  • 设计模式Python版 观察者模式
  • 深度学习-14.深度强化学习:近端策略优化
  • vscode远程连接ubuntu/Linux(虚拟机同样适用)
  • 博客系统--测试报告
  • QT-对象树
  • Linux基础开发工具——vim(5)
  • 带你深入了解前端【HTML+JavaScript】
  • web3.0简介
  • Jenkinsfile流水线构建教程
  • Vulhub靶机 AppWeb认证绕过漏洞(CVE-2018-8715)(渗透测试详解)
  • jenkens使用笔记
  • 【手撕算法】K-Means聚类全解析:从数学推导到图像分割实战
  • 解决单元测试 mock final类报错
  • 深入理解Web通信基础:HTTP响应码、请求方法与协议安全
  • Qt | 实战继承自QObject的IOThread子类实现TCP客户端(安全销毁)
  • Codeforces Round 1007 (Div. 2)(ABCD1)
  • 代码的解读——自用
  • 如何把网络ip改为动态:全面指南