コフス技術ブログ

Google フォームのURLに付与出来るクエリ文字列は8192文字まで

Google フォームではフォームURLに対しクエリ文字列(or クエリパラメーター)を付与することで特定のフォームアイテムに対しデフォルト値をセットする事が出来ますが、どうやらクエリ文字列の長さは8192を超えてはならないようです。
8192を超えるととたんにGoogle フォームは500エラーを返すようになります。

少しだけ調べてみると、RFC 2616の3.2.1にてURIの長さに制限は無いとありますので、プロトコル上ではクエリ文字列長制限などは無いようです。

The HTTP protocol does not place any a priori limit on the length of a URI.
https://www.rfc-editor.org/rfc/rfc2616#section-3.2.1

ちなみに日本語訳では以下とあります。まぁとにかく制限は無いようです。

無制限の長さのURLを扱えるべきである
https://triple-underscore.github.io/rfc-others/RFC2616-ja.html#section-3.2.1

とはいえ実態としてURIが無制限に扱える機会は無いようで、大体の場合は各ブラウザ側で万単位の文字列長で制限が掛かっているようですし、サービス側でもパフォーマンスの観点から制限を掛けている事が多いようです。
この辺りの実態は2009年のStack Overflowの回答が凄くまとまっているので参考になります。


で表題についてですが、
Googleの場合Google フォームに限らず多くの展開しているサービスでURLの全長が8192以内で制限が掛けられていると思われます。
というのもGoogle Maps Platformのドキュメントに記載されている以下の内容からも、恐らくほぼ全てのGoogle製サービスで同様の制限が掛けられているものと推測されるからです。

さらに、URL は、すべての Google Maps Platform ウェブサービスと Static Web API で 8,192 文字に制限されています。ほとんどのサービスでは、この文字制限に達することはめったにありません。ただし、複数のパラメータを持つ特定のサービスでは、URL が長くなる可能性があります。
https://developers.google.com/maps/url-encoding

8192は(2^13)で表せるように区切りとしては扱いやすい上限だったのかもしれません。Chrome拡張機能などでストレージを扱うAPIの1つにchrome.storage.syncがありますが、このAPIで保存出来る各アイテムの上限数QUOTA_BYTES_PER_ITEMも8192だったりします。(まぁ単純に環境定数だと思います。メモリ使用指定などでも8192を見かけます)


さてクエリ文字列の長さに制限があることは分かったので、実際にクエリ文字列を付与する際は以下の様にURLの長さに応じて付与の有無を分けてしまうのも良さそうです。

const getQueryParams = (): string => {
  // クエリ文字列として付与したい何らかのデータ
  const data = {}

  // 特定のフォームアイテムにクエリパラメータ付与
  const addQueryParams = `&entry.000000000=${encodeURIComponent(JSON.stringify(data, null))}`

  // 文字列長が8192を超える時はクエリパラメータを付与しない
  return addQueryParams.length > 8192 ? '' : addQueryParams
}

// Google フォームのURL
const googleFormsUrl = 'https://docs.google.com/forms/d/e/**********/viewform?usp=pp_url?'

// クエリ文字列を付与したURL
const url = googleFormsUrl + getQueryParams()

console.log(url)

Google フォームにクエリ文字列を付与する場合は500エラーにならない様、文字列の長さも気にしておきたいです。