V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
wanttte
V2EX  ›  问与答

昨天提问,碰一鼻子灰,现在真心重新求教:不依靠后端,浏览器端能不能抓其他网站的内容?

  •  
  •   wanttte · 2017-03-19 18:35:45 +08:00 · 4699 次点击
    这是一个创建于 2799 天前的主题,其中的信息可能已经有所发展或是发生改变。
    昨天的问题链接: https://www.v2ex.com/t/34852

    可以不看昨天的问题链接,问题重新描述如下:
    A 网站有 api ,但不支持跨域。 B 网站想在浏览器端,调用这个 api ,在不靠后端支持的情况下,如何能做到?

    为什么会问这个问题:
    最近 google 的 pwa 很火, google 号称要给予 native 同等的地位,很多人说这将颠覆 native 等等,于是就有了这个问题。

    如果是写 native 应用当然没有跨域问题,用 request 想抓什么就抓什么。
    但如果现在写一个 pwa 应用,就是 android 的 chrome 浏览器可以把应用放到手机桌面的,像原生应用那样有个图标。那么这个 web 应用就很受限制了,比如我想写个爬虫之类的, native 可以做得到,但 web 做不到,没法跨域。
    第 1 条附言  ·  2017-03-19 21:05:40 +08:00
    不好意思,旧贴链接少个 0 :
    https://www.v2ex.com/t/348520
    49 条回复    2017-03-21 09:02:55 +08:00
    bianhua
        1
    bianhua  
       2017-03-19 18:40:36 +08:00
    Off-topic:
    楼主你发帖能检查一下么?

    刚我还在思考 HTML5 vs Native 的问题,现在我在超市买樱桃。
    loading
        2
    loading  
       2017-03-19 18:47:05 +08:00 via Android
    用 frame 算不算?
    如果被抓网站用了措施,就不好办。


    建议楼主多读书,慢慢来,一口吃不成胖子的。
    yimity
        3
    yimity  
       2017-03-19 20:37:09 +08:00
    不一定做不到,楼主你把 A 站的情况再说详细点。
    wanttte
        4
    wanttte  
    OP
       2017-03-19 21:07:04 +08:00
    @bianhua 不好意思,旧贴链接修改好了: https://www.v2ex.com/t/348520
    wanttte
        5
    wanttte  
    OP
       2017-03-19 21:10:14 +08:00
    @loading 不考虑被抓特殊措施。比如被抓的就是一个 api : http://block.okcoin.cn/api/v1/block_height.do?block_height=404643&symbol=BTC
    wanttte
        6
    wanttte  
    OP
       2017-03-19 21:10:28 +08:00
    wanttte
        7
    wanttte  
    OP
       2017-03-19 21:10:45 +08:00
    loading
        8
    loading  
       2017-03-19 21:18:01 +08:00 via Android
    楼主你这是面向论坛编程啊……

    面向书本,面向搜索引擎编程……面向 github 编程都没人说你的。
    kookxiang
        9
    kookxiang  
       2017-03-20 02:41:04 +08:00 via Android
    naive 也要讲究基本法啊,不开放给你的 API 就算是 native 你也不能调啊
    支持跨域就跟你 native 要写个 public 一样
    wanttte
        10
    wanttte  
    OP
       2017-03-20 07:37:27 +08:00
    @kookxiang 这个 api , native 怎么不能调? web 端就不行了
    wanttte
        11
    wanttte  
    OP
       2017-03-20 07:38:53 +08:00
    @loading 发那么多字嘲讽,不如仔细看下内容
    jsq2627
        12
    jsq2627  
       2017-03-20 08:13:52 +08:00 via iPhone
    答案是不行。否则各种跨域保护机制都成摆设了。
    jsq2627
        13
    jsq2627  
       2017-03-20 08:16:55 +08:00 via iPhone
    如果是在浏览器环境下那就无解了。但是如果是构建 hybrid app ,那么有很多解决方案,比如直接在设备上运行一个 proxy 做代理。
    wanttte
        14
    wanttte  
    OP
       2017-03-20 08:23:19 +08:00
    @jsq2627 所以我的意思就是, google 推出了 pwa 这种东西,就是要把一个 web 页面当作 native app 来对待,但由于浏览器的这种安全限制,很多事情都不能做。那以后浏览器会不会有大的变革?比如跨域问题。
    dremy
        15
    dremy  
       2017-03-20 08:45:11 +08:00 via Android
    跨域问题的话写成 chrome 插件可破
    hxsf
        16
    hxsf  
       2017-03-20 09:13:50 +08:00
    @wanttte #14
    如果那个 api 是个公用的 api 接口的话,那么它应该默认就是支持跨域访问的。

    如果那个是一个非开放的 api 接口,那人家不想让你访问,有啥问题么?

    这是一个安全的问题。

    如果是你自己的,可以通过启动参数等 N 种方法,关闭 cors 。
    hxsf
        17
    hxsf  
       2017-03-20 09:14:53 +08:00
    @hxsf #16 更正: 如果是你自己的,可以通过浏览器启动参数、做成插件等 N 种方法,关闭浏览器的 cors 保护。
    imlonghao673
        18
    imlonghao673  
       2017-03-20 09:27:22 +08:00 via Android
    楼主要考虑跨域的安全性!
    楼主的问题,答案可以,请于网站方联系要求设置 CORS
    hst001
        19
    hst001  
       2017-03-20 10:49:57 +08:00 via Android
    同源策略是出于安全设计的。要跨域有几种办法,一是自己加代理服务器,二是让对方用 jsonp 的方式返回或者让对方设置允许你跨域请求。

    叫你多读书少抱怨不是数落你,如果你知道这些,也不用花时间到处问,这是最浪费时间的解决办法。
    MinonHeart
        20
    MinonHeart  
       2017-03-20 10:55:03 +08:00
    页面上实现不了,像 chrome 浏览器这种,可以借助扩展来实现
    master13
        21
    master13  
       2017-03-20 11:38:10 +08:00
    我是这么理解的, LZ 提到的 native app 的一些功能其实是 WEB 架构里所谓的“后端”才能做到的,单凭前端特别是受各种限制的前端来完成 native app 的全部,显然是不可以的。

    话说为什么不能依靠后端……前端把做不到的事当做类似于“任务”的东西( something like a task )甩给后端,前端轮询后端处理结果……现在不都是这样么……
    qiayue
        22
    qiayue  
       2017-03-20 11:41:41 +08:00
    写个简单的 chrome 插件,可以跨域请求任何 API
    Zzzzzzzzz
        23
    Zzzzzzzzz  
       2017-03-20 11:44:20 +08:00   ❤️ 1
    yahoo 的 YQL
    Zzzzzzzzz
        24
    Zzzzzzzzz  
       2017-03-20 11:45:05 +08:00
    不过这个实质上也是 yahoo 的服务端替你读了一下
    littleylv
        25
    littleylv  
       2017-03-20 11:51:15 +08:00
    想说,为啥“不依靠后端”?
    wanttte
        26
    wanttte  
    OP
       2017-03-20 14:04:53 +08:00
    @hst001 我帖子里跨域二字都写出来了,难道我还不知道跨域吗?
    帖子表达的意思是, web 能做的越来越多,现在有了 pwa 这种技术, google 声明给予和 native 同等的地位,但是 web 还是限制太多,起码这么简单的事情都做不到。
    pwa 一大用途就是可以离线使用。可不可以假设,不依靠后端,点开主屏的图标,打开 web 应用,可以调用各种 api ,抓网站数据。如果是个 native ,没任何问题吧,但 web 就是不行。
    这么说能明白我的意思了吧?
    Rice
        27
    Rice  
       2017-03-20 14:12:11 +08:00
    @wanttte 是啊,怎么了?
    wanttte
        28
    wanttte  
    OP
       2017-03-20 14:12:57 +08:00
    @master13 你是最接近理解我意思的回帖了。为什么想这些呢?
    因为 web 越来越流行,现在又有了 pwa 这种东西,可以把 web 当成一个图标放到手机桌面,对用户来说就和一个 native app 体验一样了。而且 pwa 号称可以离线,脱离后端运行。
    现在,比如写一个 native ,抓各种 api ,数据,显示结果,很普通的一个应用。但是如果用 web 就不可以,因为浏览器的安全限制。
    以后浏览器就是一切,就是一个操作系统。但浏览器就这一个同源安全限制,就做不了很多事情。
    msg7086
        29
    msg7086  
       2017-03-20 15:11:51 +08:00
    @wanttte 操作系统也可以一样做限制 —— 防火墙等等。

    你说要让 Web App 和 Native App 有一样的体验,那就意味着 ——

    浏览器放开权限管理,如操作系统一般宽松,
    - or -
    操作系统收紧权限管理,如浏览器一样严格。

    比如说 Windows 上一些 App 就是用 JS 写的( Atom etc.),软件本身就是浏览器,软件可以自己给自己放宽权限,如操作系统一般宽松。
    lecher
        30
    lecher  
       2017-03-20 15:41:41 +08:00
    你想写 native 抓各种 api ,那是因为 native 你可以任意构造请求数据,所以没有同源安全这个限制。但是浏览器不可能放开这个限制,因为浏览器托管了 cookie 这类的敏感数据是可以做用户标识的,所以发出去的请求格式有限制,不能任意构造请求。
    即便是 native 的开发,也还有存储域的限制,一个 app 如果在框架指定的私有存储域写入文件,那么别的 app 也不可以访问到这个私有存储域的文件。而且最重要的一点, native 不可以调用用户浏览器数据或者其它 app 的资源,只能靠 native 自己构造请求数据。

    而浏览器对于 web 请求,是不验证发起域的,只要发出去的请求,默认就带上该域的 cookie 作为用户标识。所以 web 目前的请求方式决定了,限制跨域是保证浏览器用户数据安全的底线,不管任何浏览器都必须支持同源安全限制。只有符合 cors 白名单的网站才可以发跨域请求。

    如果浏览器在目前的业务下可以在任意界面构造任何请求发出去,这个浏览器不可能有人会使用。如果所有浏览器都没有同源安全限制,那互联网不超过一周就崩盘了,你随便访问一个不知名的网站,它就在后台给一票网银系统构造转账请求,在你不知情的情况下,钱就消失了。对网站来说,自己站点提供的服务,图片、 api 这类的,别的网站可以不告而取,任意调用。

    你想这么做,我猜测的原因可能是,你希望在自己的网页调用别人的资源,并且是别的网站没有在 cors 开放权限的资源。这种情况下你依然想调用这个资源,那就只剩你想盗用别人的资源这个情况了。
    碰到这种不能调用的资源,要么你找对方网站在 cors 上面加上你的网站域名,允许你直接调用。要么你自己开服务器做反代,转成同域请求。


    以后浏览器如果可以任意构造请求,那就要改变浏览器的请求模式,对于非同源的域发起的请求,比如 A.com 网页中构造了一个向 B.com 的请求,那这个请求拿不到任何 B.com 存储在浏览器的数据,相当于一个独立的用户发起的请求。比如 A.com 网页向 B.com 发出的请求永远不能携带 cookie 和敏感的 header 数据。

    这种情况下,才可能出现任意网页调用任意域的 api 数据。否则只会出现更多欺诈用户的现象。对行业生态和用户都是伤害。
    Exin
        31
    Exin  
       2017-03-20 16:02:12 +08:00 via iPhone
    1. “基于浏览器”不等同于 传统网页, PWA 这类应用如果要逼近 native App ,必然会有绕过 cors 的措施。
    2. 网页中 js 不能访问无相应 cors 的 api ,现在不能,将来也不太可能。
    hst001
        32
    hst001  
       2017-03-20 16:03:36 +08:00
    @wanttte 我不知道谷歌有没有说过 pwa 跟 native 同等地位,就算有,也不是这个意思。
    为什么 pwa 不能跨域?因为它是基于 web 的, web 不能跨域是因为安全问题,如果 pwa 可以跨域,那 web 的同源策略形同虚设,木桶原理大家都懂,所以为什么 pwa 不能跨域就是这样,除非可以隔离开来使用。
    wanttte
        33
    wanttte  
    OP
       2017-03-20 16:39:12 +08:00
    @lecher @Exin @hst001 所以这就是我问题的本质,浏览器的安全策略很重要,但结果就是局限很严重。
    wanttte
        34
    wanttte  
    OP
       2017-03-20 16:46:15 +08:00
    @lecher @Exin @hst001 所以这就是我问题的本质,浏览器的安全策略很重要,但结果就是局限很严重。
    @msg7086 这种限制和你的举例,比如操作系统的防火墙,不同 app 的安全沙盒,我觉得不是一回事,不能这么举例子。
    有很多网络资源不是不让读取,不算盗取的概念。只是以前很多东西只能放后端,现在 web 够强大,够方便,未来很多东西可以放到 web 来做。
    就比如我举的那个 api 的例子,如果感兴趣可以上网站看看 api 文档。很明显这是正常使用,不算盗取。只是 api 的开发者没有考虑到会在 web 端使用,这种情况。

    所以我的意思就是,浏览器未来难道不会修改跨域的限制?肯定有一种解决方案,既能满足安全需求,又能解决跨域问题。
    浏览器最开始没有 js ,后来也没人用 ajax ,现在又了 websocket ,甚至 webassembly 。我不相信未来浏览器还会一直存在这种限制。
    binux
        35
    binux  
       2017-03-20 16:54:59 +08:00 via Android
    LZ 你口口声声说什么 pwa ,但是为什么 pwa 不能依赖后端? Facebook 的 Web app 也要脱离后端吗?
    不要和我说什么 offline ,你一个网络抓取 app , offline 一样用不了,为什么不能有后端? pwa 不是这么要求的。
    binux
        36
    binux  
       2017-03-20 17:10:19 +08:00
    而且,你知道 CORS 的 header 叫做 Access-Control-Allow-Origin 吗?它本来就是一种许可机制,不是你说 API 是公开的就是公开的,即使是公开的,别人是否允许你拿来做 web app 也是不一定的。如果你觉得是,和我们说没有用,和 okcoin 说去啊,让他们给你加访问许可啊。
    wanttte
        37
    wanttte  
    OP
       2017-03-20 17:57:59 +08:00
    @binux 别激动,就是探讨而已。我没有说 pwa 不能依赖后端。
    没有 Access-Control-Allow-Origin ,用 node.js 可不可以访问?直接写原生应用能不能访问?
    我觉得 web 越来越强大,能做的事情也应该越来越多。所以就是探讨下现在这种跨域是否合理。
    binux
        38
    binux  
       2017-03-20 18:20:05 +08:00
    @wanttte #37 没有警察,没有摄像头你就能偷能抢了吗?
    xialdj
        39
    xialdj  
       2017-03-20 18:45:02 +08:00 via iPhone
    1 首先 对楼主表示心疼 其实楼主这个问题非常值得探讨的 但是不解决这个问题 目前的应用还是可以用 pwa 写的 因为大部分应用不需要跨域请求 本身 web 完全取代 native 也是不现实的

    2 目前没有办法跨域 有个跨域比较像的技术 foreign fetch 是在缓存拦截跨域资源的时候的一个解决办法 但是和楼主这个没啥关联
    wanttte
        40
    wanttte  
    OP
       2017-03-20 19:04:46 +08:00   ❤️ 2
    @binux 我对你的这个回复非常无语,你根本不明白我在说什么
    wanttte
        41
    wanttte  
    OP
       2017-03-20 19:06:00 +08:00
    @xialdj 是的,我就是觉得这是个问题。天天都在讲跨域,就好像老在想怎么越狱,就不想想能不能把这个监狱去掉,还不影响安全。
    as463419014
        42
    as463419014  
       2017-03-20 19:21:51 +08:00
    你看到一个美女,但是还想看她的裸体
    然后发了个帖子问大家:怎么才能看美女的裸体呢,我可以上去把她的衣服扒了吗

    大家的回答是:你要看别人裸体是可以的,但是得让美女同意,自己脱了衣服给你看才行
    你不能自己上去扒别人衣服!!!
    Exin
        43
    Exin  
       2017-03-20 20:37:39 +08:00
    像是 Electron 做出来的产品是不是就是楼主要的结果?它的运作方式接近传统网页,又没有所谓的跨域限制(比如你可以写一个请求各种 API 的 Electron 作品)。
    再比如 postman(它应该不是 electron 做的吧),作为一个 Chrome App ,功能是 API 调试,它是不是受惠于 Chrome 的应用环境也已经绕开了跨域问题?

    感觉楼主纠结于“网页只能有一种标准”上了,传统 Web 和新型 Web 应用都会有的。
    CannotGetPoint
        44
    CannotGetPoint  
       2017-03-20 20:48:19 +08:00
    都惊动大神 binux 了,我想我应该出来打下 tag
    lecher
        45
    lecher  
       2017-03-20 21:16:08 +08:00
    话说楼主一直提 native 在抓取各种数据聚合上面多么多么方便,恐怕不知道马化腾已经在人大提交过打击聚合类 app 的提案,并且很多手握版权的公司都在合力起诉那些聚合类 app 的持有者,以侵权为起诉理由,颇有抓住一个就往死里揍的阵势吧。
    任何一个做原创内容的公司,都非常讨厌侵权这种事情,转载过去就算了,直接构造请求一点成本不出就占用服务器资源,这种做法等于在抢钱吧。

    类似愿意开放资源访问的,通常都在 get 接口上面开放,哪怕是 POST 或者 PUT 的业务,只要按照其文档提交的请求,都能拿到相关的资源。根本不存在楼主说的有意愿开放访问但是受限于浏览器限制没有办法开放的情况。浏览器不能构造任何请求不是行业的业务痛点,反而是浏览器这个领域保护用户的重要优点。
    楼主发的这个话题,更像是一种泄愤,为什么浏览器不能让我想盗取什么就盗取资源。我在 native 上面盗用起来何其方便,在浏览器上面怎么就这么难,这浏览器是不是要死要死了。
    yimity
        46
    yimity  
       2017-03-20 21:39:07 +08:00
    是否可以 iframe 搞一发,然后 window. 来搞。
    wanttte
        47
    wanttte  
    OP
       2017-03-20 23:59:27 +08:00
    @lecher
    1. 你这话应该对搜索引擎去说;
    2. 技术和到的绑定毫无意义;
    3. 你看看我提供的那个 okcoin 的 api 再说。
    4. 我可没有抱怨浏览器要死了,相反我觉得他未来会更强大。
    julyclyde
        48
    julyclyde  
       2017-03-21 07:32:27 +08:00
    大部分回答都是颠倒因果的
    是因为保护而不能
    不是因为不能而保护
    wizardforcel
        49
    wizardforcel  
       2017-03-21 09:02:55 +08:00 via Android
    浏览器的扩展应用可以跨域。

    完毕。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1121 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 19:01 · PVG 03:01 · LAX 11:01 · JFK 14:01
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.