JavaScriptでクエリパラメーターを書き換える

2019/06/11

累計閲覧数 2415 PV

実装コード

コピー&ペーストで動くJavaScriptのコードとしては次のようになります。 DevToolsに貼り付けで動作確認が可能です。

const stringify = (targetObject) => {
  return Object.entries(targetObject).reduce((queries, current) => {
    const key = encodeURIComponent(current[0]);
    const value = encodeURIComponent(current[1]);
    return (queries += (queries === "" ? "" : "&") + `${key}=${value}`);
  }, "")
}

const updateQueryParams = (newKey, newValue) => {
  const searchParams = new URLSearchParams(window.location.search);
  const nextQueryParams = {};
  searchParams.forEach((value, key) => {
    nextQueryParams[key] = value;
  });
  nextQueryParams[newKey] = newValue;
  history.replaceState(null, document.title, `?${stringify(nextQueryParams)}`);
}

TypeScriptバージョン

TypeScriptを利用している場合、大抵の場合はwebpackを通していると考えられるので、stringifyは少し楽をします。

import { stringify } from "querystring";

const updateQueryParams = (newKey: string, newValue: string): void => {
  const searchParams = new URLSearchParams(window.location.search);
  const nextQueryParams: { [key: string]: string } = {};
  searchParams.forEach((value, key) => {
    nextQueryParams[key] = value;
  });
  nextQueryParams[newKey] = newValue;
  history.replaceState(null, document.title, `?${stringify(nextQueryParams)}`);
}

解説

URLSearchParams

URLSearchParamsを利用してクエリパラメーターを扱いやすくします。 ただしこのAPIはInternet Explorerで未サポートであり、Safariも10以下は未サポートとなっています。 が、そういったブラウザやバージョンは進化の妨げになるので切り捨てましょう。 もし対応が必要ならURLSearchParams Polyfilを充てましょう。

const searchParams = new URLSearchParams(window.location.search);

現在のクエリパラメーターはforEachを使うと内部のgeneratorがvalue, keyを引数としてループを回します。 現在のクエリパラメーターのペアを維持しつつ、新しいクエリパラメーターに置き換えていきます。

history.replaceState

HTML5から実装されたAPIで、現在の履歴(=URL)を操作できます。 似たAPIとしてpushStateがありますが、これを利用すると履歴が増えていく違いがあります。

参考