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

JS 根据来路域名跳转不同网址问题

  •  
  •   lancn · 125 天前用 Android 发布 · 3138 次点击
    这是一个创建于 125 天前的主题,其中的信息可能已经有所发展或是发生改变。
    想用 js 实现根据不同来路域名( 2 个)跳转到不同网址
    通过 123.comwww.123.com 的来路跳转到 111.com
    通过 456.comwww.456.com 的来路跳转到 222.com
    楼主美工,代码不太懂,不知道该怎样搞,求大神指点,万分感谢!
    52 回复  |  直到 2017-06-20 08:37:49 +08:00
        1
    autoxbc   125 天前
        2
    crayygy   125 天前 via iPhone
    CNAME ? 不需要通过 js 吧
        3
    Zohar   125 天前 via Android   ♥ 1
    @crayygy CNAME 只是 DNS 记录的一种类型,和跳转没有必然联系。
        4
    lilifenghao44   125 天前
    @Zohar 他说的应该是 CNAME 会携带 servername,然后可以在 httpd 里面 vhost 分 servername (网址)
        5
    pantingwen   125 天前   ♥ 1
    根基 js 里面的 document.referrer 来判断啊!
    var referrer=document.referrer;
    if(referrer.indexOf('www.123.com')){
    window.location.href='111.com '
    };
        6
    beyoung   125 天前
    这种事情还是应该交给 Nginx、Apache 来处理吧
        7
    Zohar   125 天前 via Android   ♥ 1
    @lilifenghao44 Request Header 中是否包括 Host 信息,取决于浏览器发送的请求,与是否使用 CNAME 记录无关。

    反过来说,无论是 A 记录, AAAA 记录, CNAME 记录还是其他类型记录,只要能正确的解析到服务器 IP,并且服务端 Web Server 能判断 Host 后进行跳转,都能够达到目的,并不依赖于 CNAME 记录。
        8
    xmadi   125 天前 via iPhone
    http 请求头部里 referer 字段来判断请求来源 这个属性是浏览器强制加而且不可更改的
        9
    yhxx   125 天前
    用 refer 的话 http 和 https 互跳会出问题
        10
    aprikyblue   125 天前   ♥ 1
    上面说 CNAME 的,我认为你们需要重新粗略了解一下完成一个对网站的 HTTP 请求的流程
        11
    470326964   125 天前
    nginx 跳转一下不就好了
        12
    GoBeyond   125 天前 via Android
    看一下 window.location 然后再重新赋值给 window.location 就可以了吧。但是来讲这样的任务往往都是后端干的
        13
    qiayue   125 天前
    来路域名一般指的是 referer。
    比如你在本页面点击打开 weibo.com,那么你此次微博的来路域名就是 www.v2ex.com
    楼主的需求是,从不同的网站(一般都是别人的网站)点击打开同一 URL,能够跳转到不同的 URL。
    楼上说 nginx cname 的都是什么鬼。
    一楼已经给出解决方案了。
        14
    Chaidu   125 天前
    ```javascript
    var referring = document.referrer;
    if (referring) {
    if (referring.indexOf('123.com') !== -1) {
    window.location.replace('http://111.com/');
    } else if (referring.indexOf('456.com') !== -1) {
    window.location.replace('http://222.com/');
    }
    }
    ```
        15
    Chaidu   125 天前
    不支持 Markdown 语法?
    https://imgur.com/a/Y15Cu
        16
    Chaidu   125 天前
        17
    autoxbc   125 天前
    @Chaidu 可以用 gist,看本站说明
    https://www.v2ex.com/t/1244

    另对 url 字符串用 indexOf 匹配域名是不可靠的,比如 'http://somesite.com?str=123.com',甚至用正则也不推荐,很多跨站漏洞都是这么产生的。
        18
    Chaidu   125 天前
    @autoxbc
    首先,感谢提示。但是,你说的这些谁都懂。
    我写这些代码之前已经把所有的问题都考虑到了。
    题主需要用 javascript 代码解决一个问题,而我的代码使题主完美的达到了目的,解决了问题。
    所有不结合问题本身的质疑都是耍流氓。如果新闻报道了某地发生了一起抢劫事件,然后全世界的每个人出门都要请保镖跟随吗?我感觉实在是可笑!
        19
    EXDestroyer   125 天前
    @Chaidu 不对吧,你的代码确实是存在楼上所说的是漏洞(或者说是 bug )的,如果采用你这个方法需求逻辑会有问题的...
        20
    lslqtz   124 天前
    javascript switch.
        21
    lancn   124 天前 via Android
    感谢大家的热心回复,我会把方法卓个仔细试试,第一次在 V2EX 提问,氛围真是太棒了!
        22
    wkl17   124 天前
    @lilifenghao44 请问要怎么样获取到 cname 的来路域名?之前就隐隐约约感觉有这样的途径(如果真能实现,那就不需要在服务器上绑定新域名了,只要解析到别名就行,多爽。。。),但不知道具体是如何做的。
        23
    lilifenghao44   124 天前
    @Zohar 我只是补充#2 的, 假如 1.aaa.com cname 到 2.aaa.com, 在 httpd 中,收到的请求 host 依旧是 1.aaa.com.
    当然用 A 记录也是可以.(当然知道请求头是客户端封装的.).
    也说了重点是用 vhost 去区分 servername.
        24
    lilifenghao44   124 天前
    @aprikyblue 大家只是尽所能回复,不完整或者错误也是难免.
    您若是明白,不如做个介绍和解释,给大家普及下知识.
    如果否认能让您感觉有思想,或者功力深厚,那么恭喜你.
        25
    Tokin   124 天前
    @Chaidu 没有人质疑你,只是有人指出你代码存在潜在隐患,感觉你的回复可能有些过激了。
    而且我觉得,单纯的提供可行却不一定可靠的方案有点不负责任。
    如果老板让你开发一个功能,你实现了,但是却存在 [已知的安全隐患 BUG] 被同事指出,你能大声的告诉他你的代码“完美的达到了目的,解决了问题”吗?
    我觉得我可能也有点过激了,非常抱歉。
        26
    Tokin   124 天前
    收回上面的回复,非常抱歉,我觉得我傻了- -,这里可能只是在讨论可行方案,安全问题并不是这个主题要考虑的,非常抱歉 @Chaidu
        27
    lilifenghao44   124 天前
    @wkl17 cname 和 A 记录其实没啥区别,除了不能配缺省.
    楼主的跳转,已经有回复帖了 location 跳转代码.
    不知道具体需求,看情况用 httpd 的 rewrite,vhost 或者代码里跳转吧.
        28
    meepo3927   124 天前
    @Tokin , 不用道歉吧, 他写的代码确实简陋,打眼一看就有问题.

    @Chaidu 人家没有质疑你,而是指出了你代码的问题。你给楼主提供了思路,但是并没有“完美的达到了目的”。
        29
    Chaidu   124 天前
    @EXDestroyer #19 并不是 Bug,逻辑也并没有问题。也许你没明白我在 #18 所说,没关系,下面我再解释一下。
    @Tokin #26 对的,就是这个意思。没事,大家共同探讨问题而已。
    @meepo3927 #28 你真的完全理解题主的应用场景吗?注意,我说的是应用场景。他只是需要把两个域名的来路跳转到对应的两个页面上,仅此而已。对应他的使用场景,我给出的这段代码也许是最完美的。
    另外,你都“打一眼看就有问题”,我会看不出来?第一,只是应用题主的场景而已。第二,#17 所构造的那个情况我在写那段代码之前就已经考虑到并立刻想到三种解决方法,只是没写出来。为什么不写出来?第一,我代码都给出来了,你解决#17 说的那种情况自己就可以解决啊,解决方法很多。第二,题主举例的那四个域名并不是生产环境的域名,解决方案里的参数自然就不同,我直接给出代码你测试完美,但是在生产环境由于域名长度不同,相应的每个解决方案的参数(截取字符串的长度、判断索引的位置。具体看下面的代码。)也不相同。
    好吧,说话很简单,下面贴出代码(代码 2、代码 3 )。(由于 #17 的大神说不推荐用正则(虽然我并不知道为什么不推荐用正则),我就不写正则的方法了。)


    班门弄斧,让大神们见笑了。
        30
    Chaidu   124 天前   ♥ 1
    上图中的第 27 行 代码写错了,下面重新再贴一下代码。
        31
    aprikyblue   124 天前
    @lilifenghao44 #24
    我也没什么恶意,
    只是觉得这属于比较基础的内容,并不算什么高深内容,更遑论什么“有思想,或者功力深厚”,
    而在这看到有说 CNAME 的实在不太理解,还不止一个人。
    只是提醒一下如果有这个误区的再去了解关注一下这块知识。
    因为看到上面的 @Zohar 已经解释得比较清楚了,所以我才没具体解释。
    如果你想来探讨一下这个问题,随时欢迎。

    如果我语言不是很恰当,对你造成了困扰,那我很抱歉。
    实在看不爽,那我也没办法。拒绝撕逼,大家时间都很宝贵
        32
    EXDestroyer   124 天前
    @Chaidu 可是啊..两个域名的来路后面会带参数这是很常见的情况啊,如果直接使用 indexOf 怎么行呢,再怎么说你也不能说这是完美的解决方案吧
        33
    Chaidu   124 天前
    @EXDestroyer
    第一、带参数≠带恶意参数。
    第二,请先看帖,后回复。
    #30 中的 “代码 3 ”就是完全用 indexOf 解决的,你能找出毛病吗?
        34
    EXDestroyer   124 天前
    @Chaidu 但是别人指出你最开始的代码不完美又有什么问题呢,讨论技术就是要尽可能的把各方面都考虑到
    回复你的层主在一楼就已经给出了比较完善同时兼容性更好的方案,又没有人身攻击你,你搞得这么激动为何呢
        35
    EXDestroyer   124 天前
    @Chaidu 至于你的第三种写法,好像也不算完美吧
    123.com?a=456.com
    这样的 URL 就会跑到你的第二种条件去了,原则上应该在第一种条件
        36
    EXDestroyer   124 天前
        37
    meepo3927   124 天前
    ;(function (window, document, undefined) {
    // config
    var urlMap = {
    '123.com': 'http://111.com',
    '456.com': 'http://222.com'
    };

    var r = document.referrer;
    if (!r) {
    return;
    }
    // trip protocal
    if (r.substr(0, 7) === 'http://') {
    r = r.substr(7);
    } else if (r.substr(0, 8) === 'https://') {
    r = r.substr(8);
    }

    // parse domain
    var domain = r.split('/')[0];
    domain = domain.split('?')[0];

    // match and jump
    for (var i in urlMap) {
    if (domain.indexOf(i) >= 0) {
    window.location.replace(urlMap[i]);
    return;
    }
    }

    })(window, document);

    -----------------------------------------
    基于 @Chaidu 的加了一个 parse domain, 没严格测试,楼主可拿去参考。

    欢迎拍砖. (我也是闲的蛋疼)
        39
    meepo3927   124 天前
    上图已挂,试试这个

        40
    w88975   124 天前
    为什么不直接用 window.location.host 呢
        41
    Chaidu   124 天前
    @EXDestroyer #34 # 35 #36 你说的这些都是你自己凭空相信出来的结果。你在没有测试我的代码的前提下直接拿凭空想象出来的结果来质疑我的代码,我也真是醉了。
    @meepo3927 #37 首先感谢你分享代码(#17 说过不建议用正则。我想他说的“正则”也包括这种用字符串来匹配截取。)。
    我一开始只是想帮助题主解决当前问题,写代码之前也把所有可能出现的情况和解决方案都想到了。之所以没贴出来这些非常复杂的代码,答案是没必要,方法给题主了,题主可以视自己的应用场景而定需不需要加一些限制条件(比如:之前的那两个域名都是自己的,自己跳转到自己的两个对应网址。等等很多情况下根本不需要杞人忧天。),然后很多人就非要杞人忧天。
    说到这里很多人一定觉得我是一个做事不认真不严谨、写代码粗心大意、代码留坑留漏洞坑人,应该被老板扣工资炒鱿鱼的人。
    其实,前面说了很多次了,我只是给题主一个解决方案,他再更具自己的使用场景来确定是否需要加各种限制。
    举个栗子:你妈妈把饭做好,然后端到你的面前放好。然后你说,为什么不喂到嘴里?不是不喂你,而是不知道你是像自己吃呢,还是想让喂呢!如果喂你了,你会不会说为什么不让我自己吃呢?就像我在 #16 给出的代码,如果一开始就做了很多判断限制,题主可能觉得,我的使用场景不需要判断那些。从 123.com、456.com 过来的网址都是正常的文章页的 url。
    最后,自清一下,我写代码可是非常严禁的。就说这些吧。
        42
    Chaidu   124 天前
    @meepo3927 #39 记得 网易蜂巢 在 v2 推广时,被大家嘲笑官方示范的代码是截图的。现在看看咱们在 v2 讨论问题贴代码也是通过截图,真是讽刺。
    @lancn 题主,v2 是程序员吹牛的论坛,逛 v2 是得不到任何营养的。问问题可以去 Stack Overflow 和 SegmentFault。远离 v2,你会发现新大陆。(我几个月不逛一次 v2 )。v2 站长是出了名的心胸狭窄,应该会封我号。
        43
    q409195961   124 天前
    6L 正解,让 NG 跳更直接
        44
    Chaidu   124 天前
    @q409195961 你是不了解题主的应用场景。我之前做过一个项目就必须用 js 来跳,从而避免搜索引擎跟踪 http 的状态。不过,我做的那个项目要复杂的多,先设置 Cookies,加上 url 带参数(这个参数很复杂,有多个加密算法加密不同用户特征拼接+时间戳(从服务器获取)加密后拼接。),第二个页面判断 Cookies 并解密 url 参数和判断时间差是否大于 x 秒(为了验证是否合法,防止伪造。)。
        45
    EXDestroyer   124 天前
    @Chaidu 我觉得很无语,楼上并没有人对你人身攻击你,真的不知道你为什么莫名这么激动...
        46
    Chaidu   124 天前
    @EXDestroyer 转移话题?
        47
    EXDestroyer   124 天前
    @Chaidu 这和转移话题没有任何关系,你的言论本来就有问题
    另外你认为不需要考虑这类场景,别人认为需要考虑,这是观念问题,123.com 456.com 大家都明白只是一个假设
        48
    Chaidu   124 天前
    @EXDestroyer 请再看一遍我在 #41 第一行 对你的回复。
        49
    autoxbc   124 天前   ♥ 2
    @Chaidu 您的方法不是最佳实践,我分析一下
    1. 在 ['123.com','www.123.com'] , '111.com' 这个跳转规则中,三个域名是数据,跳转是操作。在多条规则中,数据和操作应该分离,就是一楼那种写法。#39 楼的代码也做了分离,就是这个意思。
    2. 数据分离后,操作会被抽象,您的三种方案都没做抽象,存在冗余代码。
    3. referring.indexOf('123.com') < 13 这里 13 是 Magic Number,会增加额外的维护成本。抽象度足够的话,并不需要魔数。同时,网站域名变更,魔数就是潜在的 bug,甚至是漏洞。
    4. 对 url 字符串用 indexOf 或者 match(/new RegExp/) 匹配域名,并不总可以正确匹配,如果这是安全校验的一环,会造成跨域漏洞。给你个例子看看
    http://zhchbin.github.io/2016/09/10/A-Valuable-XSS/
    5. 前端处理 url 字符串的安全做法是一楼那样,给出一篇说明,其中客户端 URL 解析部分
    http://web.jobbole.com/82459/
    6. 如果略微放松浏览器兼容性的话,我们还会构造 URL 对象,这也是安全的。
    new URL('http://www.test.com:8080/find?arg=str').hostname
    // "www.test.com"
    看这个教程,接口十分丰富,比手写好 5 倍。
    https://developer.mozilla.org/zh-CN/docs/Web/API/URL
    7. v2 是高水准程序员社区,我可能是这里最菜的一部分,但我愿意虚心向 v 友学习,希望您也可以。
        50
    Chaidu   124 天前
    @autoxbc #49 受教了,您是大神。
        51
    meepo3927   123 天前
    @w88975 window.location.host 拿的是当前 URL 的 host,需求是从来源判断,我理解就是从 referrer 中的域名来判断。
        52
    meepo3927   123 天前
    @autoxbc 大部分赞同,

    补充一下就是 new URL 的 API 在 PC 端 IE 中不行( caniuse 可查),线上项目中应该是不考虑的。
    DigitalOcean
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   鸣谢   ·   1670 人在线   最高记录 3541   ·  
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.0 · 70ms · UTC 13:56 · PVG 21:56 · LAX 06:56 · JFK 09:56
    ♥ Do have faith in what you're doing.
    沪ICP备16043287号-1