将 JSON 对象深度 Javascript 或 jQuery 转换为查询字符串
Deep Javascript or jQuery conversion of JSON object to query string
我需要帮助来解决 jQuery 的 $.param() 不够深入的问题,它会留下一些更深的 JSON 之类的东西 %5D
等等。
这不是 PayEezy 电子商务 API 的问题,但他们的沙箱 API 需要一个如下所示的查询字符串:
https://api-cert.payeezy.com/v1/securitytokens?apikey=FAKEZdp9nJrKu46wX9evGNnRbGL38W6I&js_security_key=js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1&callback=respondPEZ&auth=true&ta_token=NOIW&type=FDToken¤cy=USD&credit_card.cardholder_name=John+Doe&credit_card.card_number=4111111111111111&credit_card.exp_date=1218&credit_card.cvv=100&credit_card.type=visa&billing_address.street=&billing_address.city=&billing_address.state_province=&billing_address.zip_postal_code=&billing_address.country=&billing_address.email=&billing_address.phone.type=&billing_address.phone.number=
当你看到它时,我希望你注意到 billing_address.state
而不是 billing_address[state]
,而不是 billing_address%5Bstate%5D
。我需要 PayEezy 的特殊方式。
所以,我在 Javascript:
中创建了这个 JSON 对象
var o = {
apikey: 'FAKEZdp9nJrKu46wX9evGNnRbGL38W6I',
js_security_key: 'js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1',
callback: 'respondPEZ',
auth: true,
ta_token: 'NOIW',
type: 'FDToken',
currency: 'USD',
credit_card: {
type: 'visa',
cardholder_name: 'John Doe',
card_number: '4111111111111111',
exp_date: '1218',
cvv: '100'
},
billing_address: {
street: undefined,
city: undefined,
state_province: undefined,
zip_postal_code: undefined,
country: undefined,
email: undefined,
phone: {
type: undefined,
number: undefined
}
}
};
现在,当您 运行 通过 jQuery 的 $.param() 时,您得到的结果与查询字符串不够接近:
apikey=FAKEZdp9nJrKu46wX9evGNnRbGL38W6I&js_security_key=js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1&callback=respondPEZ&auth=true&ta_token=NOIW&type=FDToken¤cy=USD&credit_card%5Btype%5D=visa&credit_card%5Bcardholder_name%5D=John+Doe&credit_card%5Bcard_number%5D=4111111111111111&credit_card%5Bexp_date%5D=12%2F18&credit_card%5Bcvv%5D=100&billing_address%5Bstreet%5D=&billing_address%5Bcity%5D=&billing_address%5Bstate_province%5D=&billing_address%5Bzip_postal_code%5D=&billing_address%5Bcountry%5D=&billing_address%5Bemail%5D=&billing_address%5Bphone%5D%5Btype%5D=&billing_address%5Bphone%5D%5Bnumber%5D=
看到那些 %5D
和 %5B
了吗?这些是不受欢迎的,而不是 PayEezy 在 API.
中想要的
因此,我通过这样做设法更接近于解决问题:
var s = decodeURIComponent($.param(o,false));
但后来发现我可以通过这样做进一步修复它:
var s = decodeURIComponent($.param(o,false))
.replace(/\]\=/g,'=')
.replace(/\]\[/g,'.')
.replace(/\[/g,'.');
我的问题是 -- 是否有更完善的方法将对象嵌入的 JSON 对象转换为更 URL 友好的不包含方括号的查询字符串并包含点符号,并且可能比我确定的正则表达式替换技术的代码行更少?例如,jQuery 或 Javascript 中是否已经有一些功能,当它们组合在一起时,可以很好地处理这个我不知道的问题?
我已经制作了自己的递归序列化程序。希望它能按要求工作。
该函数将遍历对象的所有属性。如果值是一个对象,它会调用自己并传入一个"breadcrum"
。 breadcrum
只是函数到达其所在位置所采用的 "path" 属性。例如,如果我们查看账单地址中的 phone 类型,则传递给函数的 breadcrum
将是 billing_address.phone.
.
如果该值不是对象,则它只是将自身附加到面包屑,然后再次将自身附加到查询字符串。
如果值为 undefined
,我只是将其设置为空字符串。
var o = {
apikey: 'FAKEZdp9nJrKu46wX9evGNnRbGL38W6I',
js_security_key: 'js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1',
callback: 'respondPEZ',
auth: true,
ta_token: 'NOIW',
type: 'FDToken',
currency: 'USD',
credit_card: {
type: 'visa',
cardholder_name: 'John Doe',
card_number: '4111111111111111',
exp_date: '1218',
cvv: '100'
},
billing_address: {
street: undefined,
city: undefined,
state_province: undefined,
zip_postal_code: undefined,
country: undefined,
email: undefined,
phone: {
type: undefined,
number: undefined
}
}
};
function convertToQueryString(object, currentBreadcrum = '') {
var queryString = '';
for (var property in object) {
var potentialObject = object[property];
if (typeof potentialObject === 'undefined') {
potentialObject = '';
} // set undefined values to an empty string
if (typeof potentialObject === 'object') {
queryString += convertToQueryString(potentialObject, currentBreadcrum + property + '.');
} else {
if (currentBreadcrum === '' && queryString === '') { // don't prepend an '&' if it's the first item in the query string
queryString += currentBreadcrum + property + '=' + potentialObject;
} else {
queryString += '&' + currentBreadcrum + property + '=' + potentialObject;
}
}
}
return queryString;
}
console.log(convertToQueryString(o));
我需要帮助来解决 jQuery 的 $.param() 不够深入的问题,它会留下一些更深的 JSON 之类的东西 %5D
等等。
这不是 PayEezy 电子商务 API 的问题,但他们的沙箱 API 需要一个如下所示的查询字符串:
https://api-cert.payeezy.com/v1/securitytokens?apikey=FAKEZdp9nJrKu46wX9evGNnRbGL38W6I&js_security_key=js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1&callback=respondPEZ&auth=true&ta_token=NOIW&type=FDToken¤cy=USD&credit_card.cardholder_name=John+Doe&credit_card.card_number=4111111111111111&credit_card.exp_date=1218&credit_card.cvv=100&credit_card.type=visa&billing_address.street=&billing_address.city=&billing_address.state_province=&billing_address.zip_postal_code=&billing_address.country=&billing_address.email=&billing_address.phone.type=&billing_address.phone.number=
当你看到它时,我希望你注意到 billing_address.state
而不是 billing_address[state]
,而不是 billing_address%5Bstate%5D
。我需要 PayEezy 的特殊方式。
所以,我在 Javascript:
中创建了这个 JSON 对象var o = {
apikey: 'FAKEZdp9nJrKu46wX9evGNnRbGL38W6I',
js_security_key: 'js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1',
callback: 'respondPEZ',
auth: true,
ta_token: 'NOIW',
type: 'FDToken',
currency: 'USD',
credit_card: {
type: 'visa',
cardholder_name: 'John Doe',
card_number: '4111111111111111',
exp_date: '1218',
cvv: '100'
},
billing_address: {
street: undefined,
city: undefined,
state_province: undefined,
zip_postal_code: undefined,
country: undefined,
email: undefined,
phone: {
type: undefined,
number: undefined
}
}
};
现在,当您 运行 通过 jQuery 的 $.param() 时,您得到的结果与查询字符串不够接近:
apikey=FAKEZdp9nJrKu46wX9evGNnRbGL38W6I&js_security_key=js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1&callback=respondPEZ&auth=true&ta_token=NOIW&type=FDToken¤cy=USD&credit_card%5Btype%5D=visa&credit_card%5Bcardholder_name%5D=John+Doe&credit_card%5Bcard_number%5D=4111111111111111&credit_card%5Bexp_date%5D=12%2F18&credit_card%5Bcvv%5D=100&billing_address%5Bstreet%5D=&billing_address%5Bcity%5D=&billing_address%5Bstate_province%5D=&billing_address%5Bzip_postal_code%5D=&billing_address%5Bcountry%5D=&billing_address%5Bemail%5D=&billing_address%5Bphone%5D%5Btype%5D=&billing_address%5Bphone%5D%5Bnumber%5D=
看到那些 %5D
和 %5B
了吗?这些是不受欢迎的,而不是 PayEezy 在 API.
因此,我通过这样做设法更接近于解决问题:
var s = decodeURIComponent($.param(o,false));
但后来发现我可以通过这样做进一步修复它:
var s = decodeURIComponent($.param(o,false))
.replace(/\]\=/g,'=')
.replace(/\]\[/g,'.')
.replace(/\[/g,'.');
我的问题是 -- 是否有更完善的方法将对象嵌入的 JSON 对象转换为更 URL 友好的不包含方括号的查询字符串并包含点符号,并且可能比我确定的正则表达式替换技术的代码行更少?例如,jQuery 或 Javascript 中是否已经有一些功能,当它们组合在一起时,可以很好地处理这个我不知道的问题?
我已经制作了自己的递归序列化程序。希望它能按要求工作。
该函数将遍历对象的所有属性。如果值是一个对象,它会调用自己并传入一个"breadcrum"
。 breadcrum
只是函数到达其所在位置所采用的 "path" 属性。例如,如果我们查看账单地址中的 phone 类型,则传递给函数的 breadcrum
将是 billing_address.phone.
.
如果该值不是对象,则它只是将自身附加到面包屑,然后再次将自身附加到查询字符串。
如果值为 undefined
,我只是将其设置为空字符串。
var o = {
apikey: 'FAKEZdp9nJrKu46wX9evGNnRbGL38W6I',
js_security_key: 'js-FAKE79a767d3fea1611ae66e1c6bfd2af8f879a767d3fea1',
callback: 'respondPEZ',
auth: true,
ta_token: 'NOIW',
type: 'FDToken',
currency: 'USD',
credit_card: {
type: 'visa',
cardholder_name: 'John Doe',
card_number: '4111111111111111',
exp_date: '1218',
cvv: '100'
},
billing_address: {
street: undefined,
city: undefined,
state_province: undefined,
zip_postal_code: undefined,
country: undefined,
email: undefined,
phone: {
type: undefined,
number: undefined
}
}
};
function convertToQueryString(object, currentBreadcrum = '') {
var queryString = '';
for (var property in object) {
var potentialObject = object[property];
if (typeof potentialObject === 'undefined') {
potentialObject = '';
} // set undefined values to an empty string
if (typeof potentialObject === 'object') {
queryString += convertToQueryString(potentialObject, currentBreadcrum + property + '.');
} else {
if (currentBreadcrum === '' && queryString === '') { // don't prepend an '&' if it's the first item in the query string
queryString += currentBreadcrum + property + '=' + potentialObject;
} else {
queryString += '&' + currentBreadcrum + property + '=' + potentialObject;
}
}
}
return queryString;
}
console.log(convertToQueryString(o));