V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
hxx051
V2EX  ›  程序员

都在聚合,我也来写了个聚合搜索 —— 猫搜,给你更多想要的结果。

  •  
  •   hxx051 · 2020-01-07 20:38:13 +08:00 · 2857 次点击
    这是一个创建于 1563 天前的主题,其中的信息可能已经有所发展或是发生改变。

    猫搜: https://www.moresearch.ga


    你是否有过这种体验?遇到一个技术问题或一个关键词,一遍遍 google、baidu、知乎……、一遍遍输入、一遍遍搜索,以求获取最佳结果

    太累,这两天实在受不了,就在想有没有一个网站,有个类似百度或谷歌的输入框,输入一次,把我们关心的各个搜索引擎的结果都展示出来呢?寻觅未果(找到的不是不能用就是不符合自己需要)

    so,既然没有轮子,那就自己写一个吧

    写这种聚合类型网站,首先想到的当然是爬虫啦,不过爬虫还得依赖服务器,手头没有(穷)怎么破?没关系,那我们就用纯前端的方式去做,互联网上有很多免费的空间。这里我们选择 coding.net 提供的免费 page 服务,可以放一些静态资源,当然你选择 github 也是可以的,不过速度相对会比较慢。而后我又去 Freenom 注册了一个免费域名:)

    https://www.moresearch.ga/ 就叫「猫搜」,猫搜一下,给你更多结果。

    万事俱备,只欠东风。接下来就是代码时刻啦~

    先看下最终效果图:

    噔!噔!噔!

    对,就这么一个简单页面就可以满足我们需求了。别看它看似简单(刚开始我也是这么想的),后来我可是趟了很多坑。😓

    1. 准备搜索引擎链接地址

    类似 https://www.baidu.com/s?wd={query} 这种,使用{query}代表一个变量,即你要搜索的关键词,替换之后访问链接即可拿到搜索的结果。

    这里我给大家准备了几个:

    百度: http://www.baidu.com/s?wd={query}
    谷歌: https://www.google.com/search?q={query}
    必应: https://www.bing.com/search?q={query}
    v2ex: https://www.google.com/search?q=site:v2ex.com/t {query}
    知乎: https://www.zhihu.com/search?type=content&q={query}
    

    2. 通过 iFrame 将各搜索结果聚合到一个页面

    如刚才图示,我们想以这种界面结构去展示聚合结果,充分利用 PC 大屏的优势,提高效率

    核心技术是用 iFrame,我也想当然会 so easy。。。可是测试下访问这是什么鬼?

    emmm, 拒绝 iFrame 嵌套

    遇到这种情况,不要试图挑战浏览器策略从前端破解 /微笑脸.jpg ,最好的方式是绕道而行:

    1. 和相关网站谈商务合作……我在说什么???好当我没说
    2. 通过 api 的方式去拿
    3. 代理
    4. 逼用户使用 IE6 ??

    显然,上述方案只有第二条通过 api 去拿我们前端可以接受,而且纯前端还得是通过 ajax,拿到后在通过 iFrame 加载出来。

    核心代码:

    onSearch(inputText: string) {
        if (this.defineURL) {
          this.viewData.isLoading = true;
          this.viewData.isShowFrame = true;
          const url = this.defineURL.replace(`{query}`, inputText);
          this.urlGO = encodeURI(url);
          this.msService.httpClient.get(this.urlGO, {responseType: 'text'}) // get 请求 html
            .subscribe(value => {
              const iframe: any = document.getElementById(this.scrnIndexID);
              const iframedoc: any = iframe.contentDocument || iframe.contentWindow.document;
              iframedoc.children[0].innerHTML = value; // iFrame 加载 html
              let index = 0;
              let isFind = false;
              while (index < this.defineURL.length) {
                const number = this.defineURL.indexOf('/', index);
                if (number - 1 >= 0 && url.charAt(number - 1) !== ':' && url.charAt(number - 1) !== '/') {
                  isFind = true;
                  index = number;
                  break;
                } else {
                  index = number + 1;
                }
              }
              const htmlBaseElement = document.createElement('base');
              htmlBaseElement.href = isFind ? this.defineURL.substring(0, index + 1) : '/';
              htmlBaseElement.target = '_blank';
              iframedoc.children[0].children[0].appendChild(htmlBaseElement);// html 设置 base URL
              this.onLoad();
            }, error => {
              this.onLoad();
            });
          // this.viewData.url = this.ds.bypassSecurityTrustResourceUrl(this.urlGO);
        }
      }
    

    3. 绕不过的坑:跨域

    前端总有个绕不过的坑,那就是跨域。当我通过 api 去拿结果时,也掉到这个坑里:(

    当然解决跨域有很多种方式:jsonp、iframe、代理 /反向代理、cors等等等等。可是没有后端配合,我们前端自己去搞,貌似就只能搭建代理服务器了,而且我又没有服务器……

    终极大招

    写到这,我已心灰意冷,手里没有服务器真的啥也干不了了吗?可惜了我写这么多代码...不行

    作为自己使用,对付跨域还有个终极大招:禁止浏览器同源策略

    以 Mac 下 chrome 为例:( windows 及其他浏览器可自行百度一下)

    Mac: 
    
    1.关闭浏览器
    2.命令行下: 
    open -a "Google Chrome" --args --disable-web-security  --user-data-dir
    

    以上,我们又可以开心的搜索了:)

    ps. 若有同学知道 源站限制 iFrame 嵌套,ajax 纯前端跨域的更好解决方案的,欢迎私信赐教,感谢🙏

    更多原创尽在公众号: 「优雅的程序员呀」。程序员赚钱之道。优雅的技术,优雅的赚钱。

    关注公众号,可以加我好友交流,也可加群技术交流哦。

    26 条回复    2020-01-16 16:13:35 +08:00
    TuxcraFt
        1
    TuxcraFt  
       2020-01-07 20:42:51 +08:00
    现在的公众号都变成广告号了吧
    iamverylovely
        2
    iamverylovely  
       2020-01-07 20:49:10 +08:00
    移动百兆宽带 10s 网页还没打开,懒得等了
    niming007zh
        3
    niming007zh  
       2020-01-07 20:52:58 +08:00
    我研究过这个问题。跨域和 iframe 各种限制的根源是各大浏览器的服务对象问题。它们是面向大众的,所以目标就是设计成限制性的,若是能被绕过,就是设计失误,必须改进。因为“当所有人都自由时,就没有了自由”。 建议你不要和这种设计性问题作对抗,即使你现在绕过了,明年的补丁就会修复。
    Les1ie
        4
    Les1ie  
       2020-01-07 20:53:14 +08:00   ❤️ 1
    同源策略是浏览器安全的基础

    可是你却把他关了 :)

    想想,随便什么网站都能获取你浏览器所有的 cookie
    unicloud
        5
    unicloud  
       2020-01-07 20:53:23 +08:00 via iPhone
    你是否有过这种体验? balaba...
    ——————————————
    没有
    Les1ie
        6
    Les1ie  
       2020-01-07 20:54:28 +08:00
    没有这几个搜索引擎配合又不允许 iframe,要实现跨域的话,建议还是服务端代理吧
    niming007zh
        7
    niming007zh  
       2020-01-07 20:56:47 +08:00
    必须用后端。你简单地用后端把页面禁止 iframe 去了不行吗
    Les1ie
        8
    Les1ie  
       2020-01-07 20:57:13 +08:00
    @niming007zh #7 google 页面禁止别人 iframe 他
    daimaosix
        9
    daimaosix  
       2020-01-07 21:01:21 +08:00
    齐了,一个多吉 Doge 一个猫搜,猫狗集合了。
    canwushuang
        10
    canwushuang  
       2020-01-07 21:01:23 +08:00
    锤子 TNT 即视感
    hxx051
        11
    hxx051  
    OP
       2020-01-07 21:19:23 +08:00
    @TuxcraFt 不是,大佬。类似写博客:)
    hxx051
        12
    hxx051  
    OP
       2020-01-07 21:19:56 +08:00
    @iamverylovely 免费空间,性能有限,还请见谅
    hxx051
        13
    hxx051  
    OP
       2020-01-07 21:21:14 +08:00
    @niming007zh 要提高效率还得多用小技巧😹我也在找寻更好更方便的解决方案
    hxx051
        14
    hxx051  
    OP
       2020-01-07 21:22:09 +08:00
    @Les1ie 是啊 绕不过了,偶尔用下不访问危险网站😂
    hxx051
        15
    hxx051  
    OP
       2020-01-07 21:22:31 +08:00
    @unicloud 哈哈哈 在理😹
    hxx051
        16
    hxx051  
    OP
       2020-01-07 21:22:54 +08:00
    @niming007zh 我控制不了源站后端:(
    hxx051
        17
    hxx051  
    OP
       2020-01-07 21:23:40 +08:00
    @daimaosix 哈哈 这名字突然间就灵光一闪~
    hxx051
        18
    hxx051  
    OP
       2020-01-07 21:24:12 +08:00
    @canwushuang 罗老师,如有雷同 纯属巧合~~
    Les1ie
        20
    Les1ie  
       2020-01-07 22:47:08 +08:00
    @hxx051 #14 仍然不建议关闭本电脑的同源(甚至我之前不知道这个还能关闭的) 建议自己的服务端代码去请求 baidu google,拿到搜索结果之后给客户端,甚至用服务端反代也可以的
    hxx051
        21
    hxx051  
    OP
       2020-01-08 09:09:29 +08:00 via iPhone
    @dasenlin 大佬遇到拒绝 iframe 嵌套或跨域的问题了吗😂
    hxx051
        22
    hxx051  
    OP
       2020-01-08 09:10:05 +08:00 via iPhone
    @Les1ie 嗯,有空买台服务器搞个代理😄
    jiorix
        23
    jiorix  
       2020-01-08 10:25:04 +08:00
    地址访问不了了,是关掉了吗?
    hxx051
        24
    hxx051  
    OP
       2020-01-08 13:16:26 +08:00
    @jiorix 用的免费空间,性能有限,可重新刷新试试😕
    dasenlin
        25
    dasenlin  
       2020-01-08 15:15:30 +08:00
    @hxx051 google 是拒绝 iframe 调用的
    Duduchao
        26
    Duduchao  
       2020-01-16 16:13:35 +08:00
    感觉兄弟写得这么细致。
    不过,这种页面布局,个人感觉看起来有点累
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3216 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 28ms · UTC 13:04 · PVG 21:04 · LAX 06:04 · JFK 09:04
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.