前端面试-浏览器同源策略详解+跨域方案

15 阅读6分钟

前端面试必看:浏览器同源策略详解+跨域方案

本文专为前端面试打造,吃透同源策略定义、核心规则、安全意义、高频跨域方案,搭配代码示例+面试话术,发文、自用复盘两用,搞定90%同源策略面试题。

前言:同源策略到底有多重要?

同源策略是浏览器最核心的安全基石,也是前端面试必考题。不管是校招还是社招,面试官都会追问:什么是同源?为什么要有同源策略?常用跨域方式有哪些?原理是什么?

前端日常开发中,接口跨域、资源加载失败、本地调试报错,几乎都和同源策略相关。

一、什么是同源策略?

1. 同源的定义(面试必背)

同源:指两个URL的协议(protocol)、域名(host)、端口(port) 完全一致,只要有一项不同,就是不同源。

三要素判断:协议 + 域名 + 端口 → 三者全同=同源,缺一不同=跨域

2. 同源判断示例(一看就懂)

以 https://www.baidu.com:8080/index.html 为基准:

对比URL是否同源原因
www.baidu.com:8080/home.html✅ 同源三要素完全一致
www.baidu.com:8080/index.html❌ 跨域协议不同(https vs http)
map.baidu.com:8080/index.html❌ 跨域域名不同(www vs map)
www.baidu.com:9090/index.html❌ 跨域端口不同(8080 vs 9090)

⚠️ 小贴士:默认端口(http=80、https=443)不写时,端口判定为默认值,不一致仍跨域;IP和域名、主域和子域,均属于跨域。

3. 同源策略的核心作用

同源策略是浏览器自带的安全限制,禁止不同源的JS脚本读取、修改对方的资源,主要防范3大风险:

  • CSRF攻击:防止恶意网站盗用用户Cookie、身份信息发起请求
  • XSS窃取数据:阻止恶意脚本获取敏感页面数据
  • 资源篡改:避免非法修改DOM、Cookie、LocalStorage等存储数据

二、同源策略限制的行为(面试高频)

浏览器并非限制所有跨域行为,而是针对敏感操作做限制,这些也是面试常考点:

❌ 受限制的跨域操作

  • AJAX/Fetch 跨域请求(无法获取响应数据)
  • 读取/修改跨域页面的Cookie、LocalStorage、SessionStorage
  • 操作跨域页面的DOM节点、获取页面数据
  • 获取跨域Canvas的像素数据

✅ 不受限制的跨域操作

这些资源加载不受同源策略约束,也是前端常用的兼容方式:

  • 标签加载资源:<img>、<script>、<link>、<iframe>、<video>
  • 表单提交(form表单action跨域可提交,但无法获取返回结果)
  • 重定向跳转(window.location.href)

三、前端高频跨域解决方案(面试+实战双用)

开发中跨域是常态,面试官重点考察方案原理、适用场景、优缺点,以下是最常用的8种方案,按面试热度排序。

方案1:CORS(跨域资源共享,生产首选)

核心原理:服务端设置响应头,允许指定源访问资源,浏览器自动放行,是最规范的跨域方案。

服务端配置示例(Node/Express)
// 后端设置CORS响应头
app.all('*', (req, res, next) => {
  // 允许所有源访问(生产建议指定具体域名)
  res.header('Access-Control-Allow-Origin', '*');
  // 允许请求头
  res.header('Access-Control-Allow-Headers', 'Content-Type,Authorization');
  // 允许请求方式
  res.header('Access-Control-Allow-Methods', 'GET,POST,PUT,DELETE,OPTIONS');
  // 允许携带Cookie
  res.header('Access-Control-Allow-Credentials', true);
  next();
});
前端适配(携带Cookie)
// Fetch请求
fetch('https://api.xxx.com/data', {
  method: 'GET',
  credentials: 'include' // 允许携带Cookie
});

// Axios请求
axios.get('https://api.xxx.com/data', {
  withCredentials: true
});
优缺点
  • ✅ 支持所有请求方式、携带Cookie、安全性高
  • ✅ 生产环境标准方案,无需前端改代码
  • ❌ 依赖后端配置,简单请求无感知,复杂请求会发预检OPTIONS

方案2:JSONP(仅支持GET,老式方案)

核心原理:利用<script>标签跨域加载资源不受限,后端返回函数调用,前端执行回调获取数据。

前端代码示例
// 定义回调函数
function getData(res) {
  console.log('跨域数据:', res);
}

// 动态创建script标签发起请求
const script = document.createElement('script');
script.src = 'https://api.xxx.com/data?callback=getData';
document.body.appendChild(script);
优缺点
  • ✅ 兼容低版本浏览器(IE)
  • ❌ 仅支持GET请求,无法携带Cookie、安全性低
  • ❌ 无错误捕获机制,现在极少使用

方案3:代理服务器(开发环境首选)

核心原理:前端请求本地代理服务器,由代理转发请求到目标接口,浏览器仅同源请求,无跨域问题。

Vue/React代理配置(vue.config.js)
module.exports = {
  devServer: {
    proxy: {
      '/api': {
        target: 'https://api.xxx.com', // 目标接口域名
        changeOrigin: true, // 开启代理
        pathRewrite: {
          '^/api': ''
        }
      }
    }
  }
};
优缺点
  • ✅ 开发环境零成本、支持所有请求方式、无感知跨域
  • ❌ 仅适用于开发环境,生产需Nginx代理

方案4:Nginx反向代理(生产环境)

核心原理:Nginx统一接收前端请求,根据路径转发到不同服务,浏览器始终访问同源地址。

server {
  listen 80;
  server_name localhost;
  
  # 接口代理
  location /api {
    proxy_pass https://api.xxx.com; # 转发到目标服务
    proxy_set_header Host $host;
  }
  
  # 前端静态资源
  location / {
    root /dist;
    index index.html;
  }
}

其他常用方案(面试补充)

  • postMessage:iframe跨页面通信,适用于父子iframe交互
  • window.name:利用window.name存储跨域数据,兼容性好
  • document.domain:主域相同、子域不同场景,设置主域即可同源
  • WebSocket:WebSocket通信不受同源策略限制

四、跨域方案对比(面试快速选择)

方案支持请求适用场景推荐度
CORS所有请求生产环境、正规项目⭐⭐⭐⭐⭐
代理服务器所有请求本地开发调试⭐⭐⭐⭐⭐
Nginx代理所有请求生产环境部署⭐⭐⭐⭐
JSONP仅GET兼容老旧浏览器⭐⭐

五、面试高频问答(直接背诵)

1. 什么是同源策略?为什么需要它?

同源策略是浏览器的安全限制,要求协议、域名、端口完全一致才允许交互;目的是防范CSRF、XSS攻击,保护用户Cookie和数据安全。

2. 常见的跨域解决方案有哪些?

主流方案:CORS、代理服务器、Nginx反向代理;老式方案:JSONP;iframe场景:postMessage、document.domain。

3. CORS的简单请求和复杂请求区别?

简单请求:GET/HEAD/POST,请求头仅简单字段,直接发起请求;复杂请求:非简单请求方式/请求头,会先发送OPTIONS预检请求,通过后才发正式请求。

4. 为什么JSONP能跨域?

因为<script>标签加载资源不受同源策略限制,通过回调函数获取后端返回的数据,仅支持GET请求。

5. 前端请求跨域携带Cookie需要注意什么?

后端开启Access-Control-Allow-Credentials:true,且Origin不能为*;前端设置withCredentials/credentials:include。

面试加分话术:生产环境优先用CORS,开发用代理服务器,跨域核心是绕开浏览器同源限制,同时保证接口安全。

文末小结:同源策略是浏览器安全底线,跨域本质是突破限制的合规方案。面试重点掌握同源三要素、CORS原理、代理配置,遇到同源策略相关问题稳拿高分。

💬 跨域踩过坑的同学欢迎评论区吐槽~觉得有用记得点赞+收藏+关注,持续更新前端面试硬核干货!