リクエストstring
を介して渡すことができるJavascript オブジェクトを にエンコードする高速で簡単な方法を知っていますか?GET
いいえjQuery
、他のフレームワークはありません-単なるJavascriptです:)
リクエストstring
を介して渡すことができるJavascript オブジェクトを にエンコードする高速で簡単な方法を知っていますか?GET
いいえjQuery
、他のフレームワークはありません-単なるJavascriptです:)
このような?
serialize = function(obj) {
var str = [];
for (var p in obj)
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
return str.join("&");
}
console.log(serialize({
foo: "hi there",
bar: "100%"
}));
// foo=hi%20there&bar=100%25
編集:これは再帰オブジェクトも変換します(クエリ文字列にPHPの「配列」表記を使用)
serialize = function(obj, prefix) {
var str = [],
p;
for (p in obj) {
if (obj.hasOwnProperty(p)) {
var k = prefix ? prefix + "[" + p + "]" : p,
v = obj[p];
str.push((v !== null && typeof v === "object") ?
serialize(v, k) :
encodeURIComponent(k) + "=" + encodeURIComponent(v));
}
}
return str.join("&");
}
console.log(serialize({
foo: "hi there",
bar: {
blah: 123,
quux: [1, 2, 3]
}
}));
// foo=hi%20there&bar%5Bblah%5D=123&bar%5Bquux%5D%5B0%5D=1&bar%5Bquux%5D%5B1%5D=2&bar%5Bquux%5D%5B2%5D=3
jQuery にはこのための関数がありjQuery.param()
ます。すでに使用している場合は、それを使用できます:
http://api.jquery.com/jquery.param/
例:
var params = { width:1680, height:1050 };
var str = jQuery.param( params );
str
現在含まれているwidth=1680&height=1050
ES6 のワンライナーは次のとおりです。
Object.keys(obj).map(k => `${encodeURIComponent(k)}=${encodeURIComponent(obj[k])}`).join('&');
const querystring = require('querystring')
const obj = {
foo: 'bar',
baz: 'tor'
}
let result = querystring.stringify(obj)
// foo=bar&baz=tor
user187291によって受け入れられたソリューションへの小さな修正:
serialize = function(obj) {
var str = [];
for(var p in obj){
if (obj.hasOwnProperty(p)) {
str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
}
}
return str.join("&");
}
オブジェクトのhasOwnPropertyをチェックすると、JSLint / JSHintが満足し、オブジェクトが単純な辞書以外の場合に、オブジェクトのメソッドやその他のものを誤ってシリアル化するのを防ぎます。このページのステートメントについては、上の段落を参照してください:http: //javascript.crockford.com/code.html
さて、誰もがここに彼のワンライナーを置くようですので、ここに私のものがあります:
const encoded = Object.entries(obj).map(([k, v]) => `${k}=${encodeURIComponent(v)}`).join("&");
任意のオブジェクトを送信する必要がありますか? その場合、ユーザー エージェントと Web サーバーが受け入れる URL の長さに制限があるため、GET はお勧めできません。私の提案は、送信する名前と値のペアの配列を作成してから、クエリ文字列を作成することです。
function QueryStringBuilder() {
var nameValues = [];
this.add = function(name, value) {
nameValues.push( {name: name, value: value} );
};
this.toQueryString = function() {
var segments = [], nameValue;
for (var i = 0, len = nameValues.length; i < len; i++) {
nameValue = nameValues[i];
segments[i] = encodeURIComponent(nameValue.name) + "=" + encodeURIComponent(nameValue.value);
}
return segments.join("&");
};
}
var qsb = new QueryStringBuilder();
qsb.add("veg", "cabbage");
qsb.add("vegCount", "5");
alert( qsb.toQueryString() );
これは、受け入れられた回答のcoffeescriptバージョンです。これにより、誰かの時間を節約できます。
serialize = (obj, prefix) ->
str = []
for p, v of obj
k = if prefix then prefix + "[" + p + "]" else p
if typeof v == "object"
str.push(serialize(v, k))
else
str.push(encodeURIComponent(k) + "=" + encodeURIComponent(v))
str.join("&")
少しは顔が良くなる
objectToQueryString(obj, prefix) {
return Object.keys(obj).map(objKey => {
if (obj.hasOwnProperty(objKey)) {
const key = prefix ? `${prefix}[${objKey}]` : objKey;
const value = obj[objKey];
return typeof value === "object" ?
this.objectToQueryString(value, key) :
`${encodeURIComponent(key)}=${encodeURIComponent(value)}`;
}
return null;
}).join("&");
}
ネストされたオブジェクトを再帰的に変換する必要があり、オブジェクトに配列が含まれる場合と含まれない場合があります(また、配列にオブジェクトや配列が含まれる場合もあります)。ソリューションはもう少し複雑になります。これが私の試みです。
また、メインオブジェクトのどの深さでオブジェクトメンバーごとに記録するかを選択するオプションと、変換された配列からのメンバーにラベルを追加するかどうかを選択するオプションをいくつか追加しました。
理想的には、thingパラメータが実際にオブジェクトまたは配列を受け取るかどうかをテストする必要があります。
function thingToString(thing,maxDepth,recordLevel,markArrays){
//thing: object or array to be recursively serialized
//maxDepth (int or false):
// (int) how deep to go with converting objects/arrays within objs/arrays
// (false) no limit to recursive objects/arrays within objects/arrays
//recordLevel (boolean):
// true - insert "(level 1)" before transcript of members at level one (etc)
// false - just
//markArrays (boolean):
// insert text to indicate any members that came from arrays
var result = "";
if (maxDepth !== false && typeof maxDepth != 'number') {maxDepth = 3;}
var runningDepth = 0;//Keeps track how deep we're into recursion
//First prepare the function, so that it can call itself recursively
function serializeAnything(thing){
//Set path-finder values
runningDepth += 1;
if(recordLevel){result += "(level " + runningDepth + ")";}
//First convert any arrays to object so they can be processed
if (thing instanceof Array){
var realObj = {};var key;
if (markArrays) {realObj['type'] = "converted array";}
for (var i = 0;i < thing.length;i++){
if (markArrays) {key = "a" + i;} else {key = i;}
realObj[key] = thing[i];
}
thing = realObj;
console.log('converted one array to ' + typeof realObj);
console.log(thing);
}
//Then deal with it
for (var member in thing){
if (typeof thing[member] == 'object' && runningDepth < maxDepth){
serializeAnything(thing[member]);
//When a sub-object/array is serialized, it will add one to
//running depth. But when we continue to this object/array's
//next sibling, the level must go back up by one
runningDepth -= 1;
} else if (maxDepth !== false && runningDepth >= maxDepth) {
console.log('Reached bottom');
} else
if (
typeof thing[member] == "string" ||
typeof thing[member] == 'boolean' ||
typeof thing[member] == 'number'
){
result += "(" + member + ": " + thing[member] + ") ";
} else {
result += "(" + member + ": [" + typeof thing[member] + " not supported]) ";
}
}
}
//Actually kick off the serialization
serializeAnything(thing);
return result;
}
ここでいくつかのトップアンサーを見た後、いくつかのエッジケースにも取り組む別の実装を書きました
function serialize(params, prefix) {
return Object.entries(params).reduce((acc, [key, value]) => {
// remove whitespace from both sides of the key before encoding
key = encodeURIComponent(key.trim());
if (params.constructor === Array ) {
key = `${prefix}[]`;
} else if (params.constructor === Object) {
key = (prefix ? `${prefix}[${key}]` : key);
}
/**
* - undefined and NaN values will be skipped automatically
* - value will be empty string for functions and null
* - nested arrays will be flattened
*/
if (value === null || typeof value === 'function') {
acc.push(`${key}=`);
} else if (typeof value === 'object') {
acc = acc.concat(serialize(value, key));
} else if(['number', 'boolean', 'string'].includes(typeof value) && value === value) { // self-check to avoid NaN
acc.push(`${key}=${encodeURIComponent(value)}`);
}
return acc;
}, []);
}
function objectToQueryString(queryParameters) {
return queryParameters ? serialize(queryParameters).join('&'): '';
}
let x = objectToQueryString({
foo: 'hello world',
bar: {
blah: 123,
list: [1, 2, 3],
'nested array': [[4,5],[6,7]] // will be flattened
},
page: 1,
limit: undefined, // field will be ignored
check: false,
max: NaN, // field will be ignored
prop: null,
' key value': 'with spaces' // space in key will be trimmed out
});
console.log(x); // foo=hello%20world&bar[blah]=123&bar[list][]=1&bar[list][]=2&bar[list][]=3&bar[nested%20array][][]=4&bar[nested%20array][][]=5&bar[nested%20array][][]=6&bar[nested%20array][][]=7&page=1&check=false&prop=&key%20value=with%20spaces
別の方法 (再帰オブジェクトなし):
getQueryString = function(obj)
{
result = "";
for(param in obj)
result += ( encodeURIComponent(param) + '=' + encodeURIComponent(obj[param]) + '&' );
if(result) //it's not empty string when at least one key/value pair was added. In such case we need to remove the last '&' char
result = result.substr(0, result.length - 1); //If length is zero or negative, substr returns an empty string [ref. http://msdn.microsoft.com/en-us/library/0esxc5wy(v=VS.85).aspx]
return result;
}
alert( getQueryString({foo: "hi there", bar: 123, quux: 2 }) );
これは、オブジェクトを取得してクエリ パラメータ文字列に変換する簡単な実装です。
export function objectToQueryParams(queryParams: object): string {
return queryParams ?
Object.entries(queryParams).reduce((acc, [key, val], index) => {
const sign = index === 0 ? '?' : '&';
acc += `${sign}${encodeURIComponent(key)}=${encodeURIComponent(val)}`;
return acc;
}, '')
: '';
}
以下を使用してください:
encodeURIComponent(JSON.stringify(obj))
// elastic search example
let story ={
"query": {
"bool": {
"must": [
{
"term": {
"revision.published": 0,
}
},
{
"term": {
"credits.properties.by.properties.name": "Michael Guild"
}
},
{
"nested": {
"path": "taxonomy.sections",
"query": {
"bool": {
"must": [
{
"term": {
"taxonomy.sections._id": "/science"
}
},
{
"term": {
"taxonomy.sections._website": "staging"
}
}
]
}
}
}
}
]
}
}
}
const whateva = encodeURIComponent(JSON.stringify(story))
console.log(whateva)
ラムダの場合:
R.pipe(R.toPairs, R.map(R.join('=')), R.join('&'))({a: 'b', b: 'a'})
考慮すべきクエリ文字列の長さには制限がありますが (HTTP/s GET 呼び出しで JSON データを送信する場合と POST を使用する場合) ...
JSON.stringify ( yourJSON ) は、JSON オブジェクトから文字列を作成します。
次に、それを16進エンコードします(下のリンク)。
これは、base64 タイプの URL エンコーディング、UTF-8 文字、ネストされた JSON オブジェクトなどで発生する可能性のあるさまざまな問題に対して常に機能します。
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify