关于 https://localhost, https://127.0.0.1, CORS 那些事 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
jianglibo
V2EX    程序员

关于 https://localhost, https://127.0.0.1, CORS 那些

  •  
  •   jianglibo
    PRO
    1 天前 4761 次点击

    前端在开发的过程中有没有碰到过 CORS 的坑呢?欢迎提问,我也乐于分享(不是我更懂,只是碰到过而已)。

    mkcert可以生成证书并将证书加入操作系统的信任列表,因此将证书配置到你的测试环境之后,可以直接访问 https://localhost:3000 而不会有任何警告。 要测试类似生产环境的 CORS ,比如前后端完全分离的架构,https 必不可少。

    那么如何在局域网内完成类似的效果呢?比如 https://192.168.3.168 。或者使用 vscode remote ssh 的时候,在本地打开本地的浏览器可以访问,但是在 remote 端,有时候需要访问一下呢?也就是说需要一个分布式的 mkcert ,cert-ctrl,这个是我们写的。self-ca 在 这里生成,在每个需要访问你的测试服务的电脑上安装客户端即可。对于某些生产环境的管理页面,如果不需要公开访问,直接用自签发的 mTLS 即可。

    题外话: 有些人对文章的内容不感兴趣,对文章中提到别人的软件也没关系,唯独对提到作者自己的软件耿耿于怀,其实大可不必,最好的做法是不要去理这样的贴子如果你觉得没有价值。大家都不理它,它就自然下沉消失不见了。

    58 条回复    2026-01-29 18:45:23 +08:00
    willbeok
        1
    willbeok  
       1 天前
    能 get 到需要解决的场景问题,但这个工具的介绍有点看不太明白。mkcert 安装后浏览器会信任证书,cert-ctrl 也能自动完成信任? self-sa 是一个命令行,没看明白作用是什么,有没有这套组合的系统架构图说明一下呢
    ff521
        2
    ff521  
       1 天前
    只要不是 AI 生成的内容就好 (主要是和本站宗旨不符,回复都不能 AI,主题反而随便 AI 生成,让人感觉割裂)
    Rache1
        3
    Rache1  
       1 天前
    你想要在其机器也能获得 https 访问,只需要按照 mkcert 的说明,把证书发其他机器然后安装信任根证书就好了。


    https://github.com/FiloSottile/mkcert?tab=readme-ov-file#installing-the-ca-on-other-systems:~:text=Installing%20the%20CA,key.pem.
    jianglibo
        4
    jianglibo  
    OP
    PRO
       1 天前
    @willbeok 如果你注册一下, 这个架构就非常清晰了,cert-ctrl 登陆之后,类似于 cloudflare,tailscale 客户端,它和[中心服务器]( https://api.cjj365.cc/r/v2ex1)交互,你在 web 端的 CA ,证书全部会自动分发,这样描述你能明白吗?
    chaoshui
        5
    chaoshui  
       1 天前
    我认为解决这个问题的方式是使用代理,而不是在你的操作系统里安装莫名奇妙的证书。
    Vite/Webpack/Nextjs 不都有代理解决方案吗?
    jianglibo
        6
    jianglibo  
    OP
    PRO
       1 天前
    @Rache1 一般来说证书固定在提供服务的机器上,http server,mail server etc. 而 ca 需要导入到需要访问这个服务的机器上,mkcert 的使用场景本机,如果你要达成从其它机器访问又变成手动模式了,如果是手动模式,那么你直接用 openssl 好了。工具的目的是让你不要去折腾,或者一次性设置,在整个职业生涯中可重复利用以节约时间和脑力。
    xitler
        7
    xitler  
       1 天前
    @chaoshui +1 看的我有点莫名其妙了
    jianglibo
        8
    jianglibo  
    OP
    PRO
       1 天前
    @chaoshui 代理就是避开了 CORS ,你可能需要更深层的思考和实践。访问[这里]( https://api.cjj365.cc/r/v2ex1),然后启用 chrome 的 dev panel ,仔细观察请求,你会更深的理解这个问题。
    jianglibo
        9
    jianglibo  
    OP
    PRO
       1 天前
    @xitler 为了便于你理解,比如有一个 api 服务器, https://api.some.where.support.cors , 你从服务器一侧调用没有任何问题,但是你直接从你的浏览器调用这个 api 为发生什么, 想象一下,实践一下,不会在感到迷惑,提高了自己的水平.
    jianglibo
        10
    jianglibo  
    OP
    PRO
       1 天前
    @xitler 或者你直接从浏览器调用我的 api 服务器作为测试好了 https://api.cjj365.cc , 我的设置不允许除了 https://cjj365.cc 之外的网页调用。
    Rache1
        11
    Rache1  
       1 天前
    @jianglibo 你这不也是要在访问侧安装东西吗,mkcert 只是需要你把那个 CA 导入到访问侧的主机上就好了(基于这个 CA 生成的证书都不需要在管了),还不需要额外装软件呢。
    jianglibo
        12
    jianglibo  
    OP
    PRO
       1 天前
    @Rache1 就是涉及到 ca 的复制、导入,系统重装之后就全部要重来了,原来的证书和 ca 都不见了,cert-ctrl 不需要在机器之间复制,重装系统也没有关系。当然也不是没有代价,就是你提到的需要安装客户端。
    zcf0508
        13
    zcf0508  
       1 天前
    加证书不解决跨域问题吧
    liaozzzzzz
        14
    liaozzzzzz  
       1 天前 via Android
    nginx:?
    shintendo
        15
    shintendo  
       1 天前
    @jianglibo "代理只是避开了 CORS" 这不就是目的吗?叽里咕噜说一堆什么呢
    jianglibo
        16
    jianglibo  
    OP
    PRO
       1 天前
    @zcf0508 从机制上来说证书和 cors 关系不大,但在实际使用中密切相关。 你可以试试看,http://localhost:3000 然后 cors 请求一个 https 或者 http 的第三方站点,你就会体会到为什么相关,chrome 可能甚至不允许你用 http 跨域。
    jianglibo
        17
    jianglibo  
    OP
    PRO
       1 天前
    @shintendo 你不明白,而且也不想进步,那也没办法,我是希望能帮助到有求知心的人。避开 CORS 就代表 CORS 不需要了吗?你作为前端甚至不知道 CORS 的使用场景,还叽里咕噜。
    v2er119
        18
    v2er119  
       1 天前
    如果在代理上用,请求和响应的内容都是可以解密?
    jianglibo
        19
    jianglibo  
    OP
    PRO
       1 天前
    @v2er119 代理这个词不准确,刚才评论提到的代理都是在公司内部开发时为了避开 CORS 而为之,属于代取,但是不能暴露进入生产环境之后可能遇到的 CORS 问题。
    pingdog
        20
    pingdog  
       1 天前 via iPhone
    引用 @shintendo 的话“叽里咕噜说一堆”

    从头到尾看了两遍,才发现 OP 只是在推广自己的项目
    > 也就是说需要一个分布式的 mkcert ,cert-ctrl ,这个是我们写的。

    dev env 直接让 SRE 在 cors policy 加多一个 localhost 不就行了吗,搞这么复杂,反正 dev 上的资源随便
    xitler
        21
    xitler  
       1 天前
    @jianglibo ?那我问你,如果你这个证书,泄露了怎么办,谁都可以远程调用你的生产环境
    xdzhang
        22
    xdzhang  
       1 天前
    前段时间遇到 2 回这个情况,当时还是挺烦的.
    jianglibo
        23
    jianglibo  
    OP
    PRO
       1 天前
    @pingdog 那 Cookies + CORS 如何解决?必须用 https 了吧。:),所以在 chrome 下你无法调试登陆,在你提到的场景下,更加需要 cert-ctrl ,下次你公司碰到这个问题时,希望你能想到这个贴子。

    Cross-site cookies REQUIRE SameSite=None; Secure
    But Secure cookies cannot be set over HTTP
    jianglibo
        24
    jianglibo  
    OP
    PRO
       1 天前
    @xitler 选择 device wrapper only ,服务器端无法解密,必须时客户端的私钥解密,私钥从不离开你的服务器。
    sofukwird
        25
    sofukwird  
       1 天前
    申请个域名指向本地, 然后使用证书管理工具获取对应的证书
    jianglibo
        26
    jianglibo  
    OP
    PRO
       1 天前
    @xitler 选择有效期 6 天的证书,以保证最大的安全性。
    jianglibo
        27
    jianglibo  
    OP
    PRO
       1 天前
    @sofukwird 你的解决方案可行,但经常更新比较烦,自认证证书设个 20 年,整个职业生涯哦都不需要更新了。
    sofukwird
        28
    sofukwird  
       1 天前
    CORS 不是坑是特性
    zcf0508
        29
    zcf0508  
       1 天前
    @sofukwird #25 我的工具 https://github.com/zcf0508/unplugin-https-reverse-proxy 可以自动在本地添加 host 并且配置证书,无缝调试
    xitler
        30
    xitler  
       1 天前
    我觉得不太行,而且也根本不需要什么 https 的 localhost 。开发,测试,rc ,线上环境不做配置隔离吗,一套对一套
    ragnaroks
        31
    ragnaroks  
       1 天前
    sofukwird
        32
    sofukwird  
       1 天前
    真自签证书的话我更喜欢用 XCA 自签证书管理
    jianglibo
        33
    jianglibo  
    OP
    PRO
       1 天前
    @sofukwird XCA 是桌面程序,我的是网页版有什么区别呢?
    ltaoo1o
        34
    ltaoo1o  
       1 天前
    重点「前端开发过程的 CORS 问题」,正如前面提到,无论 vite 还是 webpack 都有解决方案并且很方便就能使用,完全没必要额外安装什么东西,尤其是根证书这种存在风险的东西。

    题外话:这就是软文,软文都是被排斥的,因为不够客观,经常是为了推自己的东西,强行构造出一个场景或者问题,从而引入自己的东西,都不考虑实际情况,就比如这篇帖子

    要推广就大大方方的推,好东西从不被排斥
    liuhuihao
        35
    liuhuihao  
       1 天前
    ?开发环境的话难道不应该是 vite 或 webpack 的 devServer 转发一下的事儿吗,如果是线上直接配一下后台的 CORS 返回头或者 nginx 代理一下不都能解决问题吗

    为啥要搞个证书嘞
    jianglibo
        36
    jianglibo  
    OP
    PRO
       1 天前
    @liuhuihao 我完全理解你的困惑,大部分人可能没有真正接触过前后端完全分离的架构,前端是静态的 html ,所有逻辑在 api 一侧,包括登陆信息等。 当 cors 遇上 cookie 时,现代浏览器会有严格的限制,甚至必须是 https 。https://cjj365.cc 是 html 的静态文件,是用静态文件生成器生成的。
    Ketteiron
        37
    Ketteiron  
       1 天前   1
    你应该更直接地表述这个工具到底解决了什么场景下的问题。
    什么时候有用?即使用 cookie 鉴权且后端设置了 SameSite=None; Secure 且需要远程访问本地运行的项目且需要保证开发环境与实际环境完全一致。
    这样就能劝退完全用不上的 99.99% 用户了。
    KellyAlsa
        38
    KellyAlsa  
       1 天前
    本地开发应该不需要搭建 https 的服务吧
    jianglibo
        39
    jianglibo  
    OP
    PRO
       1 天前
    @Ketteiron 你比大多数评论者知道其中的微妙,不是远程访问的问题,在本地调试也是一样,在需要鉴权 cookie 的情况下,本地调试也需要 https.关于工具的用处,自认证证书的签发是很小一部分功能,主要是 public 证书签发。
    adgfr32
        40
    adgfr32  
       1 天前 via Android
    生产环境是否有 cors 问题,应该通过上线前端到端测试+灰度来避免,而不是你这种奇技淫巧。
    你的做法和本地 nginx 代理没啥优势,只要上线前没有实际环境校验过,谁能保证自己方案一定过呢?
    jianglibo
        41
    jianglibo  
    OP
    PRO
       1 天前
    你根本不知道我们在说什么,问一下 @Ketteiron ,他知道。
    a132811
        42
    a132811  
       1 天前
    @zcf0508 我以前的做法,本地开发时直接用一键命令行的正向代理:证书、域名都本地生成、不侵入服务端  https://github.com/ahuigo/selfhttps
    explore365
        43
    explore365  
       1 天前
    用 openssl 或 mkcert 生成一个长期几十年的自签 CA 证书+localhost&127.0.0.1 域名证书,以后在每个测试的客户端安装这个 CA 自签证书即可。
    Ketteiron
        44
    Ketteiron  
       1 天前   3
    我来简单总结下吧。
    举个例子,本地使用 https:localhost ,浏览器需要一个受信任的证书,这里需要 mkcert 签发一个临时信任证书。
    如果从其他地方例如手机访问局域网,手机的浏览器会警告,因为它没有信任证书。
    那么"分布式" mkcert 如何提供证书,其实是服务端下发私有根证书。

    简单来说,通过自建一个私有 CA ,安装软件等于信任这个 CA ,因此不会警告。
    当然这带来了安全风险,自建方案也存在隐患。

    一般情况下 vite + vite-plugin-mkcert 就行了
    OP 的工具其实是解决了自动化复制 rootCA.pem 的操作。你说有用吧,确实有用,但我猜愿意用的没几个。
    chenluo0429
        45
    chenluo0429  
       1 天前 via Android   4
    遇到了一条河过不去怎么办?
    普通人:找负责的政府部门,建一座桥,最起码搭一座浮桥,大家都能过
    动手派:伐木自己做一条小船渡河,凑合着还能带两个人过去
    OP:你看我这里有一根绳子,还带个爪钩,你抛到对岸勾住,然后这边绑好在树上,就可以滑过去啦!你下次碰到另外的河,绳子都还可以用,船和桥就不行,这可比他们强多了。
    chenluo0429
        46
    chenluo0429  
       1 天前 via Android
    遇到了一条河过不去怎么办?
    普通人:找负责的政府部门,建一座桥,最起码搭一座浮桥,大家都能过
    动手派:伐木自己做一条小船渡河,凑合着还能带两个人过去
    OP:你看我这里有一根绳子,还带个爪钩,你抛到对岸勾住,然后这边绑好在树上,就可以滑过去啦!你下次碰到另外的河,绳子都还可以用,船和桥就不行,这可比他们强多了。
    jianglibo
        47
    jianglibo  
    OP
    PRO
       1 天前
    @Ketteiron 评论里面算比较了解 CORS 的了,不过 cert-ctrl 不仅仅分发 CA ,也完成信任操作,比如 windows,linux,freebsd,macos,firefox 等等,也分发证书(电脑重装什么的不丢)。简单说,就是本来是命令行操作,机器之间复制的行为,变成 web 端的资源,然后通过 cert-ctrl 完成这种操作,比如证书更新之后执行脚本什么的。因为我自己的系统就有大量的证书,mysql ,redis ,rabbitmq ,mail server ,http 静态服务器,api 服务器等等,需要一个统一的管理和分发机制。
    AV1
        span class="no">48
    AV1  
       1 天前
    localhost 和 127.0.0.1 即使在 http 下默认也是安全上下文,没必要 https 。
    你在 http://localhost 下执行 JS `console.log(isSecureContext)` 看它打印的是不是 true 。
    参见 https://developer.mozilla.org/en-US/docs/Web/Security/Defenses/Secure_Contexts#potentially_trustworthy_origins
    jianglibo
        49
    jianglibo  
    OP
    PRO
       1 天前
    @AV1 实践. test and verify.
    patrickyoung
        50
    patrickyoung  
       22 小时 6 分钟前
    楼主完全不懂自己写的东西。

    AI 生成 /go/promotion

    @livid
    datou
        51
    datou  
       21 小时 23 分钟前
    开发环境配上测试域名

    给测试域名签好 tls 证书

    完活儿
    sagnitude
        52
    sagnitude  
       21 小时 14 分钟前
    自己弄个便宜点的域名,弄个服务器做自动续签,弄个 crontab 定期下载到本地,开发电脑上改 hosts ,本地搭建 nginx ,浏览器直接打开 hosts 的域名,好得很,没必要死磕 localhost
    jiangzm
        53
    jiangzm  
       21 小时 7 分钟前
    全部看完了也没清楚浏览器、web 服务、cert-ctrl 、中心服务器 这四者是怎么交互的。没有条理的说一大堆还不如贴一张架构/交互图就一眼明了。

    按上面讲的 cert-ctrl 像 cloudflare ,那就是通过中间代理完成证书分发和代理请求,那问题来了用户在浏览器访问的域名是什么?还是 localhost 吗,中心服务器是用户需要部署的服务还是用你的?

    但是又好像说是通过安装代理客户端 cert-ctrl 同步自动分发的证书安装到本地?(另外多个代理不是叫分布式)
    unco020511
        54
    unco020511  
       10 小时 28 分钟前
    有一个东西叫代理,你在本地开发的时候,起个 whistle,哪有那么复杂啊
    prod.xxx.com localhost:3000
    api-prod.xxx.com locahost:5000

    你浏览器直接访问 prod.xxx.com
    你想怎么玩怎么玩,不论的你前端和服务端在哪台机器哪个环境,无所谓,代理都会帮你处理好,不存在任何跨域和证书的问题,你本地是完全和生产环境等价的
    unco020511
        55
    unco020511  
       10 小时 21 分钟前
    OP 是动脑筋思考了的,但解决方案有些绕远了
    longzhiwuing
        56
    longzhiwuing  
       6 小时 13 分钟前
    op 做的是一个『伪 CA 』,让浏览器误认为本来不被『真正 CA 』认证的域名变成『合法』的,进而『骗』过浏览器访问非公网的域名对应的服务。为什么要这么做?因为他的前端和后端接口通信得『同域』?,否则浏览器提示 CORS 错误?
    是这么理解么?
    jianglibo
        57
    jianglibo  
    OP
    PRO
       4 小时 28 分钟前
    @unco020511 如果你愿意请简单测试一下,http://localhost 返回一个 html 文件 A ,有一个 form ,username/password , 通过 ajax 发送到 http://localhost:3000 ,登陆 http://localhost:3000 ,然后在 A 页面显示登陆状态。
    先不要急着分析,先试试看。等你回复。
    jianglibo
        58
    jianglibo  
    OP
    PRO
       2 小时 46 分钟前
    @longzhiwuing 不存在真 CA 和假 CA ,只有信任的和不信任的 CA ,系统默认信任的 CA 和我愿意信任的 CA 。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2996 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 26ms UTC 13:32 PVG 21:32 LAX 05:32 JFK 08:32
    Do have faith in what you're doing.
    ubao msn snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86