一个前端,爱跑步、爱吉他、爱做饭、爱生活、爱编程、爱南芳姑娘,爱我所爱。世间最温暖又无价的是阳光、空气与爱,愿它们能带你去更远的地方。

  • 文章
  • 心情
  • 照片墙
  • 留言板
  • 工具
  • 友链
  • biaoblog

    专注web开发技术分享

    重学跨域

    技术 8 2025-11-03 13:38

    首先再次明确一点,跨域是浏览器的安全机制

    它规定的所有的请求必须同源

    • 同源(Same-Origin)条件
    • 协议相同(http / https)
    • 域名相同
    • 端口相同


    跨域报错:

    No 'Access-Control-Allow-Origin' header is present on the requested resource

    解决方案:后端在响应头加上 CORS 头,如:

    Access-Control-Allow-Origin: http://前端域名
    


    Access-Control-Allow-Origin的作用:

    Access-Control-Allow-OriginCORS(跨域资源共享)机制中的核心响应头,它告诉浏览器:

    “我允许哪些来源(域名)的前端网页访问我的接口资源。”


    补充:

    这里有个比较让人容易混洗的地方

    fetch请求中的mode可以设置cros字段,

    看起来好像是让前端请求设置了跨域请求,然后实际上不是的

    mode: 'cors' 并不是“开启跨域访问权限”的开关,而是告诉浏览器——“我要遵守 CORS 规则”。

    也就是说,它不是“放行”,而是“执行安全检查”。

    如果后端没返回正确的头:

    即便你写了:

    fetch('https://api.xxx.com', { mode: 'cors' })
    

    浏览器仍然会严格执行安全策略:

    • 检查不到 Access-Control-Allow-Origin
    • 就直接阻止前端读取响应内容
    • 抛出那句经典错误 👇
    Access to fetch at 'https://api.xxx.com' from origin 'http://xxx' 
    has been blocked by CORS policy: 
    No 'Access-Control-Allow-Origin' header is present on the requested resource.
    

    换句话说:

    mode: 'cors' 不是万能钥匙,而是「请浏览器帮我遵守跨域安全规范」。mode: 'cors' 只是声明“我要跨域”,

    真正能不能跨域,要看后端有没有给你 Access-Control-Allow-Origin


    mode的几种声明作用:

    same-origin(默认):只能请求同源资源,前后端同域部署
    cors:按 CORS 规则请求跨域资源,现代前后端分离项目
    no-cors:请求跨域资源但不能访问响应内容,加载图片、上报埋点等



    拓展:

    前端在浏览器在发起请求时,有的会直接返回请求头,有的请求甚至都没有返回头(根据请求头的Access-Control-Allow-Origin

    浏览器又是如何判断跨域了?

    这里涉及到一个新的知识点

    浏览器的预请求(OPTIONS)



    其实在预请求中返回了heads

    那么这里就要再拓展一下,浏览器什么时候会触发预请求?

    浏览器判断“要不要预检”的规则


    浏览器按照 CORS 标准,只有当请求符合以下三个条件时


    才会被认为是“简单请求(Simple Request)”,不需要 OPTIONS。

    否则就是“非简单请求(Non-simple Request)”,必须先预检。


    简单请求(不会发 OPTIONS)

    必须同时满足以下条件:


    条件说明

    1. 方法(Method)只能是 GETPOSTHEAD

    2. 请求头(Headers)只能是这几个内置安全头:

    Accept, Accept-Language, Content-Language, Content-Type(仅限下方三种取值)

    3. Content-Type只能是:

    text/plain, multipart/form-data, 或 application/x-www-form-urlencoded

    4. 请求不包含自定义头比如你手动加了 AuthorizationX-TokenX-Requested-With 等就算“非简单请求”

    满足上面这几条的 → ✅ 不发 OPTIONS,直接请求。


    非简单请求(一定会发 OPTIONS)

    只要有一条不满足上面的条件,就触发预检。


    例子 : 为什么被预检

    POST + Content-Type: application/json :Content-Type 不在允许范围内有

    Authorization : 头自定义头,必须预检

    PUTDELETE : 请求方法不在允许范围内发送带 cookie 的跨域请求浏览器会先发 OPTIONS


    所以说来说去决定是否让浏览器触发跨域抛错的还是后端接口的返回头中的Access-Control-Allow-Origin


    上一篇:没有了

    下一篇:重学js之script标签属性defer/async

    文章评论

    评论列表(0