JavaScriptでクエリ文字列を作成する方法
-
11-07-2019 - |
質問
Javascriptにフォームを取り、クエリパラメーターを返すことができる組み込みのものがあるかどうか疑問に思うだけです。例:<!> quot; var1 = value <!> amp; var2 = value2 <!> amp; arr [ ] = foo <!> amp; arr [] = bar ... <!> quot;
これは何年も疑問に思っています。
解決
しばらく前にこの質問の答えを検索しようとしましたが、フォームから値を抽出する独自の関数を書くことになりました..
完璧ではありませんが、私のニーズに合っています。
function form_params( form )
{
var params = new Array()
var length = form.elements.length
for( var i = 0; i < length; i++ )
{
element = form.elements[i]
if(element.tagName == 'TEXTAREA' )
{
params[element.name] = element.value
}
else if( element.tagName == 'INPUT' )
{
if( element.type == 'text' || element.type == 'hidden' || element.type == 'password')
{
params[element.name] = element.value
}
else if( element.type == 'radio' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
else if( element.type == 'checkbox' && element.checked )
{
if( !element.value )
params[element.name] = "on"
else
params[element.name] = element.value
}
}
}
return params;
}
form_paramsは、パラメーターの(キー-<!> gt;値)マッピングを返します。 入力はフォーム要素(DOM要素)です
複数選択を許可するフィールドは処理しません。
他のヒント
jQueryなし
var params = {
parameter1: 'value_1',
parameter2: 'value 2',
parameter3: 'value&3'
};
var esc = encodeURIComponent;
var query = Object.keys(params)
.map(k => esc(k) + '=' + esc(params[k]))
.join('&');
ES5を必要とする矢印関数構文をサポートしないブラウザーの場合、.map...
行を
.map(function(k) {return esc(k) + '=' + esc(params[k]);})
jQueryを使用している場合は、jQuery.param()
http:// apiを確認してください。 jquery.com/jQuery.param/
例:
var params = {
parameter1: 'value1',
parameter2: 'value2',
parameter3: 'value3'
};
var query = $.param(params);
document.write(query);
これはあなたの質問に直接答えるものではありませんが、クエリ文字列パラメーターを含むURLを作成する汎用関数を次に示します。パラメーター(名前と値)は、URLに含めるために安全にエスケープされます。
function buildUrl(url, parameters){
var qs = "";
for(var key in parameters) {
var value = parameters[key];
qs += encodeURIComponent(key) + "=" + encodeURIComponent(value) + "&";
}
if (qs.length > 0){
qs = qs.substring(0, qs.length-1); //chop off last "&"
url = url + "?" + qs;
}
return url;
}
// example:
var url = "http://example.com/";
var parameters = {
name: "George Washington",
dob: "17320222"
};
console.log(buildUrl(url, parameters));
// => http://www.example.com/?name=George%20Washington&dob=17320222
このためのAPI、特に URLSearchParams API 。与えられた例:
const params = new URLSearchParams();
const formvals = {
var1: "value",
var2: "value2",
arr: "foo",
};
for (const [key, val] of Object.entries(formvals)) {
params.append(key, val);
}
console.log(params.toString());
// var1=value&var2=value2&arr=foo
注: pretty最近ではChromeとFirefoxとの互換性がありますが、MicrosoftとAppleのブラウザーでの作業が必要な場合は注意してください。互換性は部分的です。
jQueryでは、$.param
$.param({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> "action=ship&order_id=123&fees%5B%5D=f1&fees%5B%5D=f2&label=a+demo"
ES2017(ES8)
コード:
const buildURLQuery = obj =>
Object.entries(obj)
.map(pair => pair.map(encodeURIComponent).join('='))
.join('&');
例:
buildURLQuery({name: 'John', gender: 'male'});
結果:
"name=John&gender=male"
いいえ、標準のJavaScriptにはそれが組み込まれているとは思いませんが、Prototype JSにはその機能があります(他のほとんどのJSフレームワークにもありますが、わかりません)。シリアル化。
Prototype JSをお勧めしますが、うまく動作します。私が本当に気づいた唯一の欠点は、サイズ(数百kb)とスコープ(ajax、domなどのコードがたくさんあること)です。したがって、フォームシリアライザーだけが必要な場合はやり過ぎです。厳密に言えば、Ajax機能だけが必要な場合(主に私が使用したものです)、やり過ぎです。注意しない限り、<!> quot; magic <!> quot;が少し多すぎることに気付くかもしれません。 (要素を見つけるためにPrototype JS関数と接触するすべてのdom要素を拡張するなど)極端な場合には遅くします。
クエリ文字列が役立ちます。
だから、次のことができます
const querystring = require('querystring')
url += '?' + querystring.stringify(parameters)
ライブラリを使用したくない場合は、同じフォーム要素タイプのほとんど/すべてをカバーする必要があります。
function serialize(form) {
if (!form || !form.elements) return;
var serial = [], i, j, first;
var add = function (name, value) {
serial.push(encodeURIComponent(name) + '=' + encodeURIComponent(value));
}
var elems = form.elements;
for (i = 0; i < elems.length; i += 1, first = false) {
if (elems[i].name.length > 0) { /* don't include unnamed elements */
switch (elems[i].type) {
case 'select-one': first = true;
case 'select-multiple':
for (j = 0; j < elems[i].options.length; j += 1)
if (elems[i].options[j].selected) {
add(elems[i].name, elems[i].options[j].value);
if (first) break; /* stop searching for select-one */
}
break;
case 'checkbox':
case 'radio': if (!elems[i].checked) break; /* else continue */
default: add(elems[i].name, elems[i].value); break;
}
}
}
return serial.join('&');
}
Prototypeでこれを行うために実際にフォームは必要ありません。 Object.toQueryString関数を使用するだけです:
Object.toQueryString({ action: 'ship', order_id: 123, fees: ['f1', 'f2'], 'label': 'a demo' })
// -> 'action=ship&order_id=123&fees=f1&fees=f2&label=a%20demo'
自分自身が完全に確信しているわけではありません。jQueryがある程度それを実行したことを思い出しますが、phpフレンドリーな方法で言うまでもなく、階層レコードをまったく処理しません。
私が確かに知っていることの1つは、URLを構築して製品をDOMに貼り付けるとき、文字列のりを使用してそれを行うのではなく、便利な改ページを開くことです。
たとえば、特定の広告ソフトウェアは、フラッシュを実行するもののバージョン文字列をインライン化します。これは一般的な単純な文字列である場合は問題ありませんが、Gnashのバージョン文字列にはURLを含む完全なGPL著作権ライセンスが含まれるため、Gnashをインストールした人にとっては非常に単純で混乱を招くことになりますおよび<!> lt; a href <!> gt;タグ。これを文字列接着剤の広告ジェネレーターで使用すると、ページが開き、不均衡なHTMLがdomに表示されます。
物語の教訓:
var foo = document.createElement("elementnamehere");
foo.attribute = allUserSpecifiedDataConsideredDangerousHere;
somenode.appendChild(foo);
しない:
document.write("<elementnamehere attribute=\""
+ ilovebrokenwebsites
+ "\">"
+ stringdata
+ "</elementnamehere>");
Googleはこのトリックを学ぶ必要があります。私は問題を報告しようとしましたが、彼らは気にしないようです。
Steinが言っているように、 http://www.prototypejs.org からプロトタイプJavaScriptライブラリを使用できます。 。
JSを含めると、非常に簡単です。$('formName').serialize()
は必要なものを返します!
jQueryを好む人にとっては、フォームプラグイン http:// pluginsを使用します。 jquery.com/project/form 。formSerializeメソッドが含まれています。
最近は、何もループすることなく、FormData
とURLSearchParams
でそれを行うことができます。
const formData = new FormData(form);
const searchParams = new URLSearchParams(formData);
const queryString = searchParams.toString();
ただし、古いブラウザにはポリフィルが必要です。
これらの回答は非常に役立ちますが、完全なURLを作成するのに役立つ可能性がある別の回答を追加します。
これは、ベースurl
、path
、hash
、およびparameters
を連結するのに役立ちます。
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
npm https://www.npmjs.com/package/build-からダウンロードできます。 url
デモ:
;(function () {
'use strict';
var root = this;
var previousBuildUrl = root.buildUrl;
var buildUrl = function (url, options) {
var queryString = [];
var key;
var builtUrl;
var caseChange;
// 'lowerCase' parameter default = false,
if (options && options.lowerCase) {
caseChange = !!options.lowerCase;
} else {
caseChange = false;
}
if (url === null) {
builtUrl = '';
} else if (typeof(url) === 'object') {
builtUrl = '';
options = url;
} else {
builtUrl = url;
}
if(builtUrl && builtUrl[builtUrl.length - 1] === '/') {
builtUrl = builtUrl.slice(0, -1);
}
if (options) {
if (options.path) {
var localVar = String(options.path).trim();
if (caseChange) {
localVar = localVar.toLowerCase();
}
if (localVar.indexOf('/') === 0) {
builtUrl += localVar;
} else {
builtUrl += '/' + localVar;
}
}
if (options.queryParams) {
for (key in options.queryParams) {
if (options.queryParams.hasOwnProperty(key) && options.queryParams[key] !== void 0) {
var encodedParam;
if (options.disableCSV && Array.isArray(options.queryParams[key]) && options.queryParams[key].length) {
for(var i = 0; i < options.queryParams[key].length; i++) {
encodedParam = encodeURIComponent(String(options.queryParams[key][i]).trim());
queryString.push(key + '=' + encodedParam);
}
} else {
if (caseChange) {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim().toLowerCase());
}
else {
encodedParam = encodeURIComponent(String(options.queryParams[key]).trim());
}
queryString.push(key + '=' + encodedParam);
}
}
}
builtUrl += '?' + queryString.join('&');
}
if (options.hash) {
if(caseChange)
builtUrl += '#' + String(options.hash).trim().toLowerCase();
else
builtUrl += '#' + String(options.hash).trim();
}
}
return builtUrl;
};
buildUrl.noConflict = function () {
root.buildUrl = previousBuildUrl;
return buildUrl;
};
if (typeof(exports) !== 'undefined') {
if (typeof(module) !== 'undefined' && module.exports) {
exports = module.exports = buildUrl;
}
exports.buildUrl = buildUrl;
} else {
root.buildUrl = buildUrl;
}
}).call(this);
var url = buildUrl('http://mywebsite.com', {
path: 'about',
hash: 'contact',
queryParams: {
'var1': 'value',
'var2': 'value2',
'arr[]' : 'foo'
}
});
console.log(url);
おそらくあなたの質問に答えるには遅すぎます。
同じ質問があり、URLを作成するために文字列を追加し続けたくありませんでした。そこで、 techhouse の説明に従って、$。paramの使用を開始しました。
URLを簡単に作成する URI.js ライブラリも見つけました。 URI.jsドキュメンテーション。
>
それらの1つを次に示します。
var uri = new URI("?hello=world");
uri.setSearch("hello", "mars"); // returns the URI instance for chaining
// uri == "?hello=mars"
uri.setSearch({ foo: "bar", goodbye : ["world", "mars"] });
// uri == "?hello=mars&foo=bar&goodbye=world&goodbye=mars"
uri.setSearch("goodbye", "sun");
// uri == "?hello=mars&foo=bar&goodbye=sun"
// CAUTION: beware of arrays, the following are not quite the same
// If you're dealing with PHP, you probably want the latter…
uri.setSearch("foo", ["bar", "baz"]);
uri.setSearch("foo[]", ["bar", "baz"]);`
var params = { width:1680, height:1050 };
var str = jQuery.param( params );
console.log(str)
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>