Help us understand the problem. What is going on with this article?

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

More than 1 year has passed since last update.

情報を引き継ぎながらリダイレクトを行う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;
    }
}();

参考になるリンク

aqril_1132
時短のために時間を惜しまず、結果として作業時間が伸びる残念な人。
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした