17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

パラメーターやリファラ情報を引き継ぎながらリダイレクトを行うJavaScriptコード

Last updated at Posted at 2018-04-09

#情報を引き継ぎながらリダイレクトを行うJavaScriptコード
.htaccessが使えない等の理由でやむなくJavaScriptでリダイレクトするときのためのコード。

単純に

location.href = 'http://example.co.jp/sp/index.html';

のようにやってしまうと、リダイレクト元ページURLのクエリパラメータ(URLの「?」の後に続く文字列)とリファラ情報(document.referrer)が拾えなくなってしまうので、
リダイレクト元ページのクエリパラメータをそのままリダイレクト先URLにくっつけ、更にリファラ情報もクエリパラメータreferrerの名前でくっつけてリダイレクトを行うようにした。
リダイレクト先URLに#keyのようにフラグメント部が含まれていることも考慮している。

##動作例
たとえば、以下のような状況でリダイレクトコードが動作したとき、

コードを埋め込むページURL http://example.co.jp/product/2359/index.html?quux=corge&grault=garply

コードが動作したときのリファラ http://example.co.jp/search?q=book&camp=springSale2018

コード内で指定したリダイレクト先URL
http://example.co.jp/sp/product/2359/index.html?foo=bar&baz=qux#key

このコードは、
http://example.co.jp/sp/product/2359/index.html?foo=bar&baz=qux&quux=corge&grault=garply&referrer=http%3A%2F%2Fexample.co.jp%2Fsearch%3Fq%3Dbook%26camp%3DspringSale2018#keyにリダイレクトする。

このURLをパーツごとに分解すると以下のようになる。

###生成されるリダイレクト先URLの分解

コード内で指定していたリダイレクト先URLのindex.htmlの部分まで
http://example.co.jp/sp/product/2359/index.html?foo=bar&baz=qux

クエリ部のはじまりを示す半角疑問符?
?

コード内で指定していたリダイレクト先URLのクエリパラメータ部分
foo=bar&baz=qux

パラメタ同士を繋ぐアンパサンド&
&

リダイレクト元ページに付いていたクエリパラメータ
quux=corge&grault=garply

パラメタ同士を繋ぐアンパサンド&
&

リダイレクト元ページのリファラ情報
referrer=http%3A%2F%2Fexample.co.jp%2Fsearch%3Fq%3Dbook%26camp%3DspringSale2018

コード内で指定していたリダイレクト先URLのフラグメント部
#key

##コード
スマートフォンからのアクセス時にJavaScriptによりスマートフォン向けページにリダイレクトが必要な状況を想定している。スマートフォンであるかどうかの判定にはこちらのコードを使用している。
別の条件が必要であればisMobile部分を書き換えるなりすればOK。

###スマホからのアクセス時に別ページに移動させるためのコード(コメントなし)

mobileRedirect.js
!function() {
    var newPage = 'https://example.com/sp/index.html?hoge=hoga#id';
    var isMobile = (function() {
        var ua = navigator.userAgent.toLowerCase();
        var sdev = /iphone;|(android|nokia|blackberry|bb10;).+mobile|android.+fennec|opera.+mobi|windows phone|symbianos/;
        return sdev.test(ua);
    })();
    if (isMobile) {
        var separatednewPage = newPage.match(/(^https?:\/\/[^?#]+)(?:\?([^#]*))?(#.*)?$/);
        var newOriginPath = separatednewPage[1];
        var newFlagment = separatednewPage[3];
        var oldReferrer = document.referrer ? 'referrer=' + encodeURIComponent(document.referrer) : '';
        var oldQuery = location.search.slice(1);
        var newQuery = [separatednewPage[2], oldQuery, oldReferrer].filter(function(q) {
            return !!q
        }).join('&');
        var newLocation = newOriginPath;
        if (newQuery) {
            newLocation = newLocation + '?' + newQuery;
        }
        if (newFlagment) {
            newLocation = newLocation + newFlagment;
        }
        location.href = newLocation;
    }
}();

###デバイスに関係なくリダイレクトさせるコード

mobileRedirect.js
!function() {
    var newPage = 'https://example.com/sp/index.html?hoge=hoga#id';
    var separatednewPage = newPage.match(/(^https?:\/\/[^?#]+)(?:\?([^#]*))?(#.*)?$/);
    var newOriginPath = separatednewPage[1];
    var newFlagment = separatednewPage[3];
    var oldReferrer = document.referrer ? 'referrer=' + encodeURIComponent(document.referrer) : '';
    var oldQuery = location.search.slice(1);
    var newQuery = [separatednewPage[2], oldQuery, oldReferrer].filter(function(q) {
        return !!q
    }).join('&');
    var newLocation = newOriginPath;
    if (newQuery) {
        newLocation = newLocation + '?' + newQuery;
    }
    if (newFlagment) {
        newLocation = newLocation + newFlagment;
    }
    location.href = newLocation;
}();

###スマホからのアクセス時に別ページに移動させるためのコード(コメントつき)

mobileRedirect.js
/**
 * スマートフォンからのアクセス時に指定したURLにリダイレクトするコード
 * リダイレクト元ページのGETパラメタとリファラをリダイレクト先のGETパラメタに追加することで、
 * リダイレクト先でもこれらの情報を利用できるようにしている。
*/
!function() {

    /**
     * リダイレクト先のURLを指定します。
     * @type {string}
     */
    var newPage = 'https://example.com/sp/index.html?hoge=hoga#id';

    /**
     *  スマートフォンからのアクセスであるかを示す真偽値です。
     * @type {boolean}
     */
    var isMobile = (function() {
        var ua = navigator.userAgent.toLowerCase();
        var sdev = /iphone;|(android|nokia|blackberry|bb10;).+mobile|android.+fennec|opera.+mobi|windows phone|symbianos/;
        return sdev.test(ua);
    })();
    
    if (isMobile) {
        /**
         * 指定されたリダイレクト先URLを正規表現により、プロトコル+ドメイン+パス部、GETパラメタ部、フラグメント部に分けた文字列です。
         * @type {string}
         */
        var separatednewPage = newPage.match(/(^https?:\/\/[^?#]+)(?:\?([^#]*))?(#.*)?$/);

        /**
         * 指定された飛び先URLのプロトコルからパス部までを示す文字列です。 e.g.'http://hoge.com/sp/index.html'
         * @type {string}
         */
        var newOriginPath = separatednewPage[1];

        /**
         * 指定されたリダイレクト先URLのフラグメント部を示す文字列です。 e.g.'#fragment'
         * @type {string}
         */
        var newFlagment = separatednewPage[3];

        /**
         * 今のページのリファラ情報であるdocument.referrerの値を示す文字列です。 e.g.'referrer=http%3A%2F%2Fhoge.com%2FprevPage'
         * リダイレクト先のGETパラメタに付与してリダイレクト先のページでも利用できるようにします。
         * @type {string}
         */
        var oldReferrer = document.referrer ? 'referrer=' + encodeURIComponent(document.referrer) : '';

        /**
         * 今のページのGETパラメタであるlocation.searchから先頭の「?」を除いた結果を示す文字列です。 e.g.'foo=bar&baz=qux'
         * リダイレクト先のGETパラメタに付与してリダイレクト先のページでも利用できるようにします。
         * @type {string}
         */
        var oldQuery = location.search.slice(1);

        /**
         * 実際のリダイレクト先URLに設定するGETパラメタすべてを&で結合した結果を示す文字列です。 e.g.'foo=bar&baz=qux&oldq=oldk&referrer=http%3A%2F%2Fhoge.com%2FprevPage'
         * リダイレクト先のGETパラメタに付与してリダイレクト先のページでも利用できるようにします。
         * @type {string}
         */
        var newQuery = [separatednewPage[2], oldQuery, oldReferrer].filter(function(q) {
            return !!q
        }).join('&');

        /**
         * 実際の飛び先URLを示す文字列です。 e.g.'http://hoge.com/sp/index.htmlfoo=bar&baz=qux&oldq=oldk&referrer=http%3A%2F%2Fhoge.com%2FprevPage'
         * @type {string}
         */
        var newLocation = newOriginPath;
        if (newQuery) {
            newLocation = newLocation + '?' + newQuery;
        }
        if (newFlagment) {
            newLocation = newLocation + newFlagment;
        }
        location.href = newLocation;
    }
}();

##参考になるリンク

17
18
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
18

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?