如何解决js跨域问题

在前端开发中,由于浏览器的同源策略,不同源(协议、域名、端口任意一个不同)的页面之间进行数据交互会受到限制,这就是跨域问题。以下为你介绍几种常见的解决 JavaScript 跨域问题的方法,并举例说明:

1. JSONP(JSON with Padding)

  • 原理:JSONP 利用了 <script> 标签的 src 属性不受同源策略限制的特点。它的基本思想是通过动态创建 <script> 标签,向服务器请求一个 JSON 数据,并在请求的 URL 中添加一个回调函数名作为参数。服务器收到请求后,会将 JSON 数据包装在这个回调函数中返回给客户端。客户端的 <script> 标签会执行这个回调函数,从而获取到服务器返回的数据。
  • 示例
    • 服务器端(Node.js + Express)
const express = require('express');
const app = express();

app.get('/data', (req, res) => {
    const callback = req.query.callback;
    const data = { message: 'Hello from the server!' };
    const jsonp = `${callback}(${JSON.stringify(data)})`;
    res.send(jsonp);
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});
- **客户端(HTML + JavaScript)**
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>JSONP Example</title>
</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 是一种现代的跨域解决方案,它是 W3C 标准,允许浏览器和服务器进行跨域通信。服务器通过设置响应头来告诉浏览器哪些跨域请求是被允许的。当浏览器发起跨域请求时,会先发送一个预检请求(OPTIONS 请求),询问服务器是否允许该请求。服务器返回相应的响应头后,浏览器根据响应头决定是否继续发送实际请求。
  • 示例
    • 服务器端(Node.js + Express)
const express = require('express');
const app = express();

// 允许所有域名进行跨域调用
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: 'Hello from the server!' };
    res.json(data);
});

const port = 3000;
app.listen(port, () => {
    console.log(`Server is running on port ${port}`);
});
- **客户端(HTML + JavaScript)**
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>CORS Example</title>
</head>

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

</html>
  • 优点:支持所有 HTTP 请求方法,是目前主流的跨域解决方案。

3. 代理服务器

  • 原理:在同源的服务器上设置一个代理,客户端将请求发送到同源的代理服务器,代理服务器再将请求转发到目标服务器,并将目标服务器的响应返回给客户端。这样,客户端和代理服务器是同源的,不会受到同源策略的限制。
  • 示例(Vue.js 项目中使用代理)
    • vue.config.js 中配置代理
module.exports = {
    devServer: {
        proxy: {
            '/api': {
                target: 'http://example.com', // 目标服务器地址
                changeOrigin: true,
                pathRewrite: {
                    '^/api': ''
                }
            }
        }
    }
};
- **客户端代码**
fetch('/api/data')
  .then(response => response.json())
  .then(data => console.log(data));
  • 适用场景:在开发环境中使用较为方便,生产环境需要在服务器端进行相应配置。
posted @ 2017-06-02 02:28  皇问天  阅读(1219)  评论(0)    收藏  举报