请教前端大佬:一个很蛇皮的跨域问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
ChatGPTPRO
V2EX    程序员

请教前端大佬:一个很蛇皮的跨域问题

  •  
  •   ChatGPTPRO 2023-10-10 10:42:42 +08:00 4483 次点击
    这是一个创建于 731 天前的主题,其中的信息可能已经有所发展或是发生改变。

    打开这个地址: https://api.likepoems.com/img/bing/

    它会自动跳转到一个图片的地址,然后可以看到浏览器 url 变化了。

    我想在代码中先 axios 请求这个地址,获取到真实的图片地址以及 base64 ,但是它报跨域了。这个地址是网上公共的,所以走允许跨域是走不通。

    在代码中直接用 window.open("https://api.likepoems.com/img/bing/") 这个方式是可以成功打开这个地址且显示图片的。

    我也想过用浏览器父子窗口通信的方式来获取上述需要的信息,但是也没解决。

    41 条回复    2023-10-12 04:29:18 +08:00
    ChatGPTPRO
        2
    ChatGPTPRO  
    OP
       2023-10-10 10:53:47 +08:00
    @MrYELiex 阿这阿这
    7inFen
        3
    7inFen  
       2023-10-10 10:55:17 +08:00
    前端没法处理,postMessage 也是需要源网站配合才可以
    liuhuihao
        4
    liuhuihao  
       2023-10-10 10:56:46 +08:00
    源站不是你的不配合的话,无解。考虑非前端的方式吧,比如提前在后台把 重定向的地址跑出来然后返回给前端
    ChatGPTPRO
        5
    ChatGPTPRO  
    OP
       2023-10-10 11:03:42 +08:00
    @liuhuihao

    其实这个图片可以显示出来,那是不是意味着 html 里面就加载了,那是不是 base64 是能拿到的呢。至少说这个图片数据

    @7inFen
    xiaohundun
        6
    xiaohundun  
       2023-10-10 11:06:39 +08:00
    你用的人家的 API 不是已经提供了一个获取图片信息的接口了么,里面有 url
    xiaohundun
        7
    xiaohundun  
       2023-10-10 11:07:07 +08:00
    liuhuihao
        8
    liuhuihao  
       2023-10-10 11:09:00 +08:00
    @ChatGPTPRO #5 你最终目的是什么呢?
    如果说只是想要在你的页面里嵌入人家的这张图片,iframe 就可以实现正如你所说的可以正常显示。但是你想拿到图片的 base64 啥的在我了解的范围内前端是没法实现的,只能后台实现
    liuhuihao
        9
    liuhuihao  
       2023-10-10 11:11:42 +08:00
    @liuhuihao #8 除非对方接触跨域的限制或者提供不限制跨域的接口
    7inFen
        10
    7inFen  
       2023-10-10 11:13:34 +08:00
    @ChatGPTPRO 图片显示是渲染引擎 WebKit 的工作,不存在跨域;操作 base64 是 js 引擎 V8 的工作,有跨域限制。
    weixiangzhe
        11
    weixiangzhe  
       2023-10-10 11:13:37 +08:00
    做个反代吧
    ChatGPTPRO
        12
    ChatGPTPRO  
    OP
       2023-10-10 11:15:27 +08:00
    @xiaohundun 大佬你咋这么强啊
    xiaohundun
        13
    xiaohundun  
       2023-10-10 11:18:28 +08:00
    @ChatGPTPRO #12 可能你没看 API 主的网站吧,这接口应该还允许跨域,我没试
    676529483
        14
    676529483  
       2023-10-10 11:18:53 +08:00
    如果只是显示图片,img 标签不需要跨域
    gogogo2000
        15
    gogogo2000  
       2023-10-10 11:19:14 +08:00
    @ChatGPTPRO #5 对浏览器来说确实是获得到了,但是浏览器会限制非同域的脚本,不允许你获得图片的任何信息
    ChatGPTPRO
        16
    ChatGPTPRO  
    OP
       2023-10-10 11:22:13 +08:00
    @xiaohundun 大佬,确实可以得到真实的图片地址。

    ```
    {
    "code": 200,
    "url": "https://jihulab.com/weblog/gallery02/-/raw/master/BingImage/2021-06-16/OHR.GBRTurtle_ZH-CN6069093254_UHD.jpg",
    "width": 5164,
    "height": 2905,
    "size": "2386539",
    "mime": "image/jpeg"
    }
    ```

    但是有个问题,怎么获取这个图片的 base64 呀
    xiaohundun
        17
    xiaohundun  
       2023-10-10 11:29:43 +08:00
    @ChatGPTPRO #16 4 楼给你解释过了,虽然 img 可以渲染但是你要请求图片还是会碰到跨域问题,所以后端
    xiaohundun
        18
    xiaohundun  
       2023-10-10 11:33:07 +08:00
    @ChatGPTPRO #16 你试下这个,https://stackoverflow.com/questions/46609800/canvas-crossorigin-anonymous-cors-chrile-mac-osx ,说是吧 img 绘制成 canvas 然后再转
    mxT52CRuqR6o5
        19
    mxT52CRuqR6o5  
       2023-10-10 11:35:10 +08:00
    跨域图片(如果没加允许跨域的那些 headers ),没做防盗链的话,你可以用 img 加载展示,但你无法获取具体的数据( ajax 、fetch )
    你想把这个 img 画到 canvas 上都是做不到的
    之前甚至有人研究旁路攻击去偷跨域图片内容的操作( https://www.secrss.com/articles/3102 ,能偷的不止有图片)
    mxT52CRuqR6o5
        20
    mxT52CRuqR6o5  
       2023-10-10 11:38:28 +08:00
    @mxT52CRuqR6o5 #19
    又回忆了一下,「画到 canvas 上都是做不到的」说的有问题,不是做不到,而是如果把跨域 img 画到 canvas 上,就没法再对这个 canvas 执行 toBlob 、toDataUrl 这种拿到 canvas 画的内容的操作了
    liuhuihao
        21
    liuhuihao  
       2023-10-10 11:39:16 +08:00
    @xiaohundun #18 这个操作应该也是不行的,接口虽然允许跨域,但是这个图片地址的请求没返回 Access-Control-Allow-Origin ,还是不允许跨域的。不允许跨域的图片只能用 img 渲染出来,canvas 也会有跨域问题,我的知识范围内也是不可行的。
    liuhuihao
        22
    liuhuihao  
       2023-10-10 11:40:29 +08:00
    @liuhuihao #21 canvas 能画出来但是跨域的不能调用 toDataUrl 我记得
    liuhuihao
        23
    liuhuihao  
       2023-10-10 11:43:16 +08:00
    @ChatGPTPRO #12 综上所述,自己后台整个 反代解千愁
    solobat
        24
    solobat  
       2023-10-10 11:46:42 +08:00
    实在不行就用 https://deno.dev/ 代理下解决
    liuhuihao
        25
    liuhuihao  
       2023-10-10 11:47:28 +08:00
    我突然间有个疑问,浏览器的同源策略本身是为了防 A 网站非法调用 B 网站的接口,例如 A 网站是个冒牌的银行网站,然后调用 真银行的接口获取用户名密码一类的。

    但是反代可以绕过同源策略,A 网站只需要在自己的后台搭一套反向代理去请求 B 网站,一样可以骚操作模拟别的网站哈,感觉 浏览器这个同源策略也是 防君子不防小人哈哈,没啥卵用?
    heishu
        26
    heishu  
       2023-10-10 11:49:28 +08:00   1
    恕我直言,在座的各位都是~~~~~大佬
    realJamespond
        27
    realJamespond  
       2023-10-10 11:50:31 +08:00
    用 nodejs 就行了
    pkoukk
        28
    pkoukk  
       2023-10-10 11:55:10 +08:00
    @liuhuihao #25
    同源策略是为了防止你在 A 站使用 B 站的 cookie,localstorage 这些信息。
    如果没有同源策略,那么假如用户在 A 站登录了,登录信息在 A 站的 cookie 里,那么你的 B 站就可以直接调 A 站的接口
    有了之后,你就算搭了一套反代,B 站想用 A 站的接口,也得让用户在 B 站里,用 A 站的账户密码登录一次,这玩意叫钓鱼网站
    7inFen
        29
    7inFen  
       2023-10-10 11:56:07 +08:00
    @liuhuihao 是可以的,所以要提防在陌生网站输入账号密码
    sunfkny
        30
    sunfkny  
       2023-10-10 11:56:27 +08:00
    这个极狐 GitLab 仓库 https://jihulab.com/weblog/gallery02 不能跨域可以换一个,原始仓库是 https://github.com/myseil/BingWallpaper , 直接移花接木到 github
    https://gist.github.com/sunfkny/9855f30e0e9eaaef7b81d67e0c860150
    clue
        31
    clue  
       2023-10-10 13:52:42 +08:00
    @liuhuihao #25 如果你在浏览器同源策略规则外访问到了跨域数据,那证明这个浏览器有安全漏洞

    你说的反向代理问题,浏览器在请求不同域时,cookie 等信息都是完全隔离的。在浏览器这里,站点 A 的请求,只会带上 A 这个域的信息,所以你服务端的代理没任何作用

    同源策略本身是定义于浏览器的,HTTP 协议上的 cors 也只是它的延伸,最终服务于浏览器
    AV1
        32
    AV1  
       2023-10-10 14:17:54 +08:00
    @liuhuihao
    “同源策略” 的本质是不同应用之间的数据隔离。你把每个网站都看成一个 APP ,各 APP 都只能访问自己的数据,不就显得很天经地义了吗?
    所谓 “防 A 网站非法调用 B 网站的接口”,不过是应用数据隔离的附带效果罢了。
    unco020511
        33
    unco020511  
       2023-10-10 14:42:56 +08:00
    @liuhuihao #25 你说的是「钓鱼网站」,用户本身是需要在「钓鱼网站」输入账号密码的.浏览器的同源策略是隔离不同 domain 下的 cookie 等信息的,防止另一个网站直接拿你的信息去做请求
    leonshaw
        34
    leonshaw  
       2023-10-10 14:50:56 +08:00
    @liuhuihao 除了前面几楼所说的防止 A 使用 B 域的浏览器存储,还有一种情形是 A 可能访问不到 B 。例如 B 是一个没有鉴权的内网服务,如果没有同源策略,在公网的 A 就可以利用用户浏览器作跳板访问到 B 的资源。
    zuotun
        35
    zuotun  
       2023-10-10 15:22:00 +08:00
    如果只是拿到 bing 壁纸的话, 还有一大堆类似的. 我自己也做了一个(不做存储) https://api.kazusa.cc/bing
    至于解决办法, 还是反代最简单.
    yangjirun
        36
    yangjirun  
       2023-10-10 15:49:46 +08:00
    nginx 代理吧。最简单。
    JaaaaackZheng
        37
    JaaaaackZheng  
       2023-10-10 17:22:10 +08:00
    你的目的只是想将图片转 base64 ?
    JaaaaackZheng
        38
    JaaaaackZheng  
       2023-10-10 17:22:55 +08:00
    https://juejin.cn/post/6844903961141444615 用 canvas 就可以了,canvas 设置跨域就能转。我之前的项目转过
    okakuyang
        39
    okakuyang  
       2023-10-10 17:41:30 +08:00 via iPhone
    @JaaaaackZheng 跨域的图片转出来是白色的,你最好确认一下你以前的代码哦
    lmw2616
        40
    lmw2616  
       2023-10-10 18:00:14 +08:00
    request({
    method: 'get',
    url: 'https://api.likepoems.com/img/bing/',
    responseType:'arraybuffer',
    success: (res) => {

    //图片流转 blob
    let imageType = res.header['content-type'];
    const blob = new Blob([res.data], { type: imageType })

    //blob 转 base64
    let oFileReader = new FileReader()
    oFileReader.Onloadend= function (e) {
    //base64 字符串
    const base64 = e.target.result
    }
    oFileReader.readAsDataURL(blob)
    }
    })
    YuJianrong
        41
    YuJianrong  
       2023-10-12 04:29:18 +08:00
    @JaaaaackZheng 当你在一个 Canvas 里用 DrawImage 绘制一非同源又没有 CORS 的图片的时候,这个 Canvas 会处于“被污染”( tainted )状态了。处于“被污染”状态的 Canvas 这些调用将会抛错:
    * Context 上的 getImageData()
    * Canvas 上的 toBlob(), toDataURL() 和 captureStream()
    这样来防止比如 OP 这种想抓图片内容的做法。

    详情: https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image#security_and_tainted_canvases
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5648 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 40ms UTC 06:32 PVG 14:32 LAX 23:32 JFK 02:32
    Do have faith in what you're doing.
    ubao 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