ページ移動のときにGET送信かPOST送信を使って任意の値を2ページ間で受け渡す方法。
サイト内で別のページに移動をするときに、セッションやクッキーで実装するほどでもない簡単な値の送受信をしたかったので、HTTPリクエストのGETメソッドまたはPOSTメソッドを使って任意の値を受け渡す方法のメモ。
※ 受け渡した値は、データベースにアクセスしたりメール送信したりなどの用途ではないのでセキュリティーは考慮しない。
※ ページ移動が必要無い2ページ間の値の受け渡しの場合は、AjaxやcURLなどで処理する。
任意の値を移動先のページに送信
GET送信かPOST送信で移動先のページに任意の値を送る方法。
- 方法1 : ページに設置した通常のフォームから値を送信する。
- 方法2 : ページにフォームを設置せず、リンククリックなどのイベント発火時にJavaScriptで動的にフォーム生成、値の代入、送信までを実行する。
- 方法3 : GET送信の場合ならフォーム送信は不要なので、移動先のURLに送信したい値をクエリパラメーターとして付与し、URLの一部として送信する。(URLの末尾に「?」を記述し、その直後に「キー名=値&キー名=値」の形式で記述。)
1. 通常のフォームで値を送信する方法
HTMLに記述した通常のフォームで送信する方法。
※ 送信にJavaScriptなど不要だが、サイト閲覧者がフォームの送信ボタンをクリックする必要がある。
ページ内にフォームを設置して、input要素などで送信したいパラーメーターを設定、submitボタンをクリックしたら指定したリクエストメソッドで指定したURLに内容を送信して移動する。(一般的なフォームの通常の挙動。)
- form要素のaction属性に「送信先(移動先)のURL」、method属性に「get」か「post」を指定。
- input要素のname属性とvalue属性を設定。(送信したいパラメーターの「キー名」と「値」。)
- type属性をsubmitにしたbutton要素で内容を送信。
※ 送信するパラメーターをサイト上に表示させたくない場合は、input要素のtype属性を「hidden」にしてname属性とvalue属性の値はJavaScriptで動的に設定するなどで対処する。
<form action="送信先のULR" method="メソッドを指定">
<input type="text" name="任意のキー名_01" value="送信したい値_01">
<input type="text" name="任意のキー名_02" value="送信したい値_02">
<button type="submit">送信</button>
</form>
2. フォームを設置せず、リンククリックで値を送信する方法
フォームをページ内に設置せずに、a要素のリンククリックで移動先のページに任意の値を送信する方法。
何らかのリンクボタンがクリックされたら、JavaScriptでform要素を自動生成して送信内容の設定、submitの実行までを代行する。
下記の処理を関数化し、a要素のクリックイベントで発火させる。
(自サイト以外へのリンクの場合は処理を実行せずにそのままリンク先へ移動させる。)
- a要素がクリックされたら移動先のURLが自サイトか判定。
- 通常のa要素の機能を無効化してリンク先への遷移をキャンセル。
- form要素を生成して、action属性に「a要素のhref属性値」、method属性に「post」を代入。
- 生成したform要素をbody要素内に挿入。
- input要素を生成して、name属性とvalue属性に任意の値を代入。(送信したいパラメーターの「キー名」と「値」。)
- 生成したinput要素を、生成済みのform要素に挿入。
- submit()メソッドでフォーム送信を実行してa要素のリンク先に移動。
※ GET送信の場合はフォーム作成部分が不要になるので、通常のリンクの遷移をキャンセルした時点で、windowオブジェクトからlocationオブジェクトを参照し、hrefプロパティーに送信したいURLを設定して移動する。(「location.href = ‘移動先URL?キー名=値&キー名=値’;」)
//送信したい任意のパラメーターをオブジェクトに格納
const ag2sendParams = {
'キー名_01':'値_01',
'キー名_02':'値_02',
'キー名_03':'値_03'
};
//リンククリック時に実行する関数を作成
const ag2send = function(e){
//移動先が自サイトなら実行
if(e.target.hostname === location.hostname){
//アンカーの機能を無効化
event.preventDefault();
//form要素を作成してbody要素に挿入
const formForSend = document.createElement('form');
formForSend.style.display = "none";//styleを設定
formForSend.method = 'post';//method属性を設定
formForSend.action = e.target.href;//action属性を設定
document.body.appendChild(formForSend);
//ag2sendParamsに格納した要素の数だけinput要素を作成してform要素に挿入
const inputForPost = [];
let i = 0;
for(const [k, v] of Object.entries(ag2sendParams)){
inputForPost[i] = document.createElement('input');
inputForPost[i].setAttribute('type', 'hidden');//type属性を設定
inputForPost[i].setAttribute('name', k);//name属性を設定
inputForPost[i].setAttribute('value', v);//value属性を設定
formForSend.appendChild(inputForPost[i]);
i++;
}
//リンク先へ送信して移動
formForSend.submit();
}
};
//a要素のNodelistを取得
const anchorLinks = document.querySelectorAll('a');
//取得されたa要素の数
const anchorLinksNum = anchorLinks.length;
//すべてのa要素にイベントリスナーを登録
for(let i = 0; i < anchorLinksNum; i++){
anchorLinks[i].addEventListener('click', ag2send);
}
event.target : イベントを発生させたオブジェクトへの参照。オブジェクトは自身の情報をプロパティーに持つ。
location : windowオブジェクトのプロパティー。locationオブジェクトは、現在のページに関する情報をプロパティーに持ち、取得または設定ができる。(ブラウザ上で実行されるJavaScriptではwindowオブジェクトはグローバルオブジェクトなので、「window.location」の「window.」は省略できる。)
event.preventDefault() : eventオブジェクトのメソッド。発生したイベントの規定の動作を行わない。イベントの伝播は止めない。
document.createElement(‘タグ名’) : 指定したタグ名のHTML要素を生成する。
親ノード.appendChild(‘ノード’) : 指定した親ノードの子ノードリストの末尾に引数で指定したノードを追加する。
Object.entries(‘オブジェクト’) : 引数に指定したオブジェクトが所有する文字列を、[key, value]となる配列に変換して返す。(for…in文と違いprototypeを参照しない。)
document.フォーム名.submit() : 指定したフォームを送信する。
document.querySelectorAll(‘セレクター’) : 指定したセレクターのNodelistオブジェクトをDOMから取得する。
Nodelistオブジェクト.length : Nodelist内のitemの数を返す。
対象要素.addEventListener(‘イベントのタイプ’, ‘関数’, ‘イベント伝播順’) : 対象要素に指定のイベントでコールする関数を指定して登録。第3引数(初期値 : false)でイベントの伝播する方向を指定できる。falseでDOM階層の下位から上位に伝播。
送信されてきた値を移動先のページで取得
GET送信またはPOST送信されてきた値を、JavaScriptかPHPで取得する方法。
1. JavaScriptで値を取得する方法
[ GETメソッドの場合 ]
JavaScriptのURL APIを利用してURLに含まれるクエリからパラメーターの「キー」と「値」を取得する。(URL APIのMozillaの公式ドキュメント。)
[ POSTメソッドの場合 ]
クライアントサイドで実行されるJavaScriptでは取得ができないのでPHPを使う。
(1) GETメソッドで送られてきた値の取得
URLSearchParamsオブジェクトが持つメソッドを使う。
- locationオブジェクトのプロパティーから「現在のページのURL」を取得。
- 「現在のページのURL」でURLオブジェクトを生成。
- 生成したURLオブジェクトからURLSearchParamsオブジェクトを取得。
- URLSearchParamsオブジェクトのメソッドを使って、送信されてきたパラメーターを取得。
※ IEはJavaScriptのURL APIに未対応でこの方法は使えないので、URLの文字列を自力で分解して取得する。(後述。)
(2) URLSearchParamsオブジェクトが持つ主なメソッド (URLSearchParamsのmozillaの公式ドキュメント。)
メソッド | 動作内容 |
get() | 引数に指定したキーが持つ最初の値を返す。 |
has() | 引数に指定したキーが存在するかを真偽値で返す。 |
forEach() | すべてのキーと値をコールバック関数に渡して実行。 |
entries() | すべてのキーと値のペアを取得するためのiterator(オブジェクト)を返す。 |
keys() | すべてのキーを取得するためのiterator(オブジェクト)を返す。 |
values() | すべての値を取得するためのiterator(オブジェクト)を返す。 |
sort() | キーを基準にしてソートする。 |
//URLオブジェクトを作成(URLクラスでインスタンスを生成)
const currentUrl = new URL(location.href);
//URLSearchParamsオブジェクトを取得
const queryString = currentUrl.searchParams;
//取得方法1 : キー名を指定して値を取得
const receivedValue = queryString.get('任意のキー名');
//取得方法2 : forEach文ですべてのキーと値を取得して任意のオブジェクトに格納
const receivedParams = {};
queryString.forEach(function(v,k){
receivedParams[k] = v;
});
console.log(receivedParams);
//取得方法3 : iteratorからすべてのキーと値のペアを取得
const receivedParams = queryString.entries();
for(const param of receivedParams){
console.log(param[0]);//キー
console.log(param[1]);//値
}
new URL(‘任意のURL’) : 指定したURLを参照するURLオブジェクトを作成して返す。(URLコンストラクターで生成したインスタンスにプロパティーを追加。)
URLオブジェクト.searchParams : URLオブジェクトの読み取り専用プロパティー。URLに含まれるGETデコードされたクエリ引数へのアクセスが可能なURLSearchParamsオブジェクトを返す。
(3) IEに対応した方法
URL内の「キー」と「値」を自力で切り出す。
送信されたパラメーターを含んだURLをsplit()メソッドで分解して、パラーメーター内にあるすべての「キー」と「値」を任意のオブジェクトに格納する。
//キーと値を格納するための空オブジェクトを作成
let receivedParams = {};
//URLを取得してクエリ部分で分割して配列化
const queryString = location.href.split('?');
//URLにクエリがあるか判定
if(queryString.length >= 2){
//パラメーターが複数あれば分割して配列化
const queryParams = queryString[1].split('&');
//パラメーターの数だけ処理
const queryParamNum = queryParams.length;
for(let i = 0; i < queryParamNum; i++){
//パラメーターをキーと値で分割
let eachParam = queryParams[i].split('=');
receivedParams[eachParam[0]] = eachParam[1];
}
}else{
//URLにクエリが無ければnullを返す
receivedParams = null;
}
console.log(receivedParams);
対象文字列.split(‘区切り文字’) : 区切り文字で分割して配列で返す。文字列内の区切り文字は削除される。区切り文字が無ければ対象文字列をそのまま返す。
配列.length : 配列の要素の数を取得または設定する。
2. PHPで値を取得する方法
PHPのスーパーグローバル変数(スクリプト全体を通してすべてのスコープで使用可能な変数)から値を取得する。
GETメソッドで送信されてきた場合は「$_GET」(ゲット変数)、POSTメソッドで送信されてきた場合は「$_POST」(ポスト変数)に値が自動的に格納されている。変数のデータ型は配列で、連想配列として使用する。(渡される値は自動的にurldecode()関数を介している。)
※ HTMLに出力表示する場合、必要があればhtmlspecialchars()関数でエスケープ処理をする。
//パラメーターを指定して値を取得する方法
$value = $_GET['任意のパラメーターのキー名']
//すべてのキーと値のペアを取得して出力する方法
if(isset($_GET)){
foreach($_GET as $k => $v){
echo $k;
echo $v;
}
}
- JavaScriptでPOST通信(HTMLのformタグなし)
- URLに含まれるGETパラメータを取得する
- 十六章第二回 イテレータ
- 【JavaScript】 Iterator(イテレーター)とは?避けて通りたいけど説明してみる
https://memo.ag2works.tokyo/post-2005/
ページ移動のときにGET送信かPOST送信を使って任意の値を2ページ間で受け渡す方法。 | memo メモ [AG2WORKS]
<a href="https://memo.ag2works.tokyo/post-2005/" target="_blank" rel="noopener">ページ移動のときにGET送信かPOST送信を使って任意の値を2ページ間で受け渡す方法。 | memo メモ [AG2WORKS]</a>
この記事へのコメント (2件)
formForPost ってどっからでてきたんだ・・・
記述ミスだったので修正しました。
修正前「formForPost.appendChild(inputForPost[i]);」→修正後「formForSend.appendChild(inputForPost[i]);」
やってることは、上で生成したformにappendしてるだけです。