Pythonで開発していて、フォームの配列パラメータを送信したら上手く受け取れず、原因が分からずはまりました。
配列パラメータを受け取れなかった原因
配列パラメータにブラケット()を付ける付けないの違いが原因です。
PHP
PHPだと、配列パラメータは ブラケット()を付けて送受信します。
names[]=1&names=2
Pytonh
これがPythonだと、ブラケット不要になります。
names=1&names=2
それぞれの違い
- Python (Requests),key=a&key=b,キーを単に繰り返す (標準仕様に近い)
- PHP,key=a&key=b,キーに [] を付与して繰り返す
他言語間の受け渡しでは、どちらかが違いを吸収する必要がある
例えばjQueryで実現するなら、何もしないとPHP型の配列パラメータになるため、専用オプション(traditional)を利用します。
$.ajax({
url: '/api',
method: 'POST',
// Python (Flask/Django) や Java, .NET などの「キーをそのまま繰り返す形式」を好むサーバーに送る場合は、traditional: true というオプションを追加します。
traditional: true, // <--- これを追加!
data: {
tags: ['python', 'php']
}
});
// 送信されるデータ: tags=python&tags=php
Gemini 3 による分類
ブラケットあり言語
言語 / フレームワーク,役割,解説 PHP,受信側,$_POSTがこの形式を期待しており、[]がないと配列として解釈されません。 Ruby on Rails,受信側,パラメータの自動解析(パーサー)がこの形式に基づいています。 Node.js (Express),受信側,qsライブラリ(Expressでよく使われる)がデフォルトで深いネストをサポートするため、ブラケット形式を好みます。 jQuery (Default),送信側,デフォルト設定 (traditional: false) がこのブラケット形式で送信します。
ブラケットなし言語
言語 / フレームワーク,役割,解説
Python (Django/Flask),受信側,request.form.getlist('key')など、重複したキーをリストとして取得するメソッドを使います。[] はキー名の一部として認識されます。
Java (Spring),受信側,"getParameterValues(""key"")や @RequestParam List<String> key などで、重複キーをそのままリストとしてバインドします。"
Go (net/http),受信側,"標準ライブラリの r.Form[""key""] などが重複キーを自動でスライス(配列)にします。"
C# (ASP.NET),受信側,モデルバインディングが重複キーをリスト型にマッピングします。
Python (Requests),送信側,デフォルトで配列をこのキー重複形式で送信します。
jQuery (traditional: true),送信側,このオプションを有効にすると、ブラケットなしのこの形式で送信します。
あとがき
プログラミング言語によって挙動が異なるため、フォーム内の配列パラメータの取り扱いは要注意であることが分かりました。
application/x-www-form-urlencoded を明確に意識することは今まで少なかったため、勉強になります。