前端 SPA 跨域问题及解决方案详解

什么是跨域问题?

跨域问题是指在浏览器中,当一个网页的 JavaScript 代码向不同域名(或端口、协议)的服务器发送请求时,浏览器会根据同源策略禁止这种行为,从而导致请求失败。

同源策略是浏览器的一项安全策略,它规定了一个域名下的 JavaScript 代码只能访问与该域名同源的资源,也就是协议、域名、端口都要相同。

SPA 跨域问题的表现

在前端单页应用(SPA)中,常常会出现跨域问题,比如:

  1. Ajax 请求时,浏览器会阻止跨域请求,导致请求失败。
  2. 在 iframe 中加载不同域名的页面时,浏览器也会阻止访问,导致无法加载页面。
  3. 在使用 WebSocket 进行跨域通信时,浏览器同样会阻止连接。

解决方案

JSONP

JSONP 是一种跨域解决方案,它利用了 <script> 标签不受同源策略限制的特性,通过在客户端动态创建一个 <script> 标签,向服务器请求一个 JSON 数据,服务器将该数据包装在一个回调函数中返回给客户端,客户端再执行该回调函数,从而实现跨域数据的获取。

示例代码:

function jsonp(url, callback) {
  const script = document.createElement('script');
  script.src = url + '&callback=' + callback;
  document.body.appendChild(script);
}

jsonp('https://example.com/api?param=value', 'handleResponse');
function handleResponse(data) {
  console.log(data);
}

CORS

CORS(Cross-Origin Resource Sharing)是一种官方的跨域解决方案,它需要服务器设置相关的响应头,告诉浏览器哪些跨域请求是允许的。

示例代码:

// Node.js 服务器
const http = require('http');

const server = http.createServer((req, res) => {
  res.setHeader('Access-Control-Allow-Origin', '*');
  res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE');
  res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
  if (req.method === 'OPTIONS') {
    res.statusCode = 204;
    res.end();
    return;
  }
  // 处理请求...
});

server.listen(3000);
// 前端代码
fetch('https://example.com/api', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ param: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

反向代理

反向代理是一种服务器端的跨域解决方案,它利用了服务器之间的通信不受同源策略限制的特性,将客户端的请求转发到目标服务器上,再将目标服务器的响应返回给客户端,从而实现跨域请求的访问。

示例代码:

// Node.js 服务器
const http = require('http');
const httpProxy = require('http-proxy');

const proxy = httpProxy.createProxyServer();

const server = http.createServer((req, res) => {
  proxy.web(req, res, {
    target: 'https://example.com'
  });
});

server.listen(3000);
// 前端代码
fetch('http://localhost:3000/api', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ param: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));

总结

跨域问题是前端开发中常见的问题,需要了解相关的解决方案,才能更好地应对。在实际开发中,可以根据具体情况选择合适的解决方案,从而保证应用的稳定性和安全性。

来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/65c42ccaadd4f0e0ffe9e800