与jQuery.param()等价的纯Javascript
获取一个键值对数组,并将其转换为可以在HTML请求中用作查询字符串的字符串。比如说,与jQuery.param()等价的纯Javascript,javascript,jquery,ajax,google-apps-script,params,Javascript,Jquery,Ajax,Google Apps Script,Params,获取一个键值对数组,并将其转换为可以在HTML请求中用作查询字符串的字符串。比如说, a = { userid:1, gender:male } 会变成 userid=1&gender=male 我试图在Google应用程序脚本中调用服务器端的外部API,这需要很长的查询字符串。我会使用jqueryparam函数,但在谷歌的服务器端使用jQuery似乎并不容易 您能给我一些实现相同功能的简单javascript代码吗? 它的jQuery实现是,但我不想
a = {
userid:1,
gender:male
}
会变成
userid=1&gender=male
我试图在Google应用程序脚本中调用服务器端的外部API,这需要很长的查询字符串。我会使用jqueryparam函数,但在谷歌的服务器端使用jQuery似乎并不容易
您能给我一些实现相同功能的简单javascript代码吗?
它的jQuery实现是,但我不想冒险跳过任何关键细节,简单地复制它并删除处理“传统”的代码。您也可以使用纯JavaScript来实现,但您必须编写更多的代码行。试试这个: 用于测试的HTML代码:
<p id="test"></p>
输出如下:
userid=1&gender=male
你可以在JSFIDDLE.NET上试试这个,它很有效,下面是链接:@Amaynut的答案非常棒。但我做了一些简化:
const obj = {
userid: 1,
gender: 'male'
}
const params = Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k])).join('&')
或者使用es6模块将其模块化:
util.js
export default {
params (obj) {
return Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k])).join('&')
}
}
然后像这样使用:
import util from './util'
const q = {
userid: 1,
gender: 'male'
}
const query = util.params(q)
console.log(query)
请在此处查看它的实际操作:
导出函数参数(params){
const p=新的URLSearchParams;
for(对象项(参数)的常量[键,值]){
p、 设置(键、字符串(值));
}
返回p.toString();
}
ES6版本,该版本允许转换嵌套对象和数组,只需使用类似的encodeURI(getUrlString({a:1,b:[true,12.3,“string”]}))
这有点令人沮丧。这里的解决方案似乎都不能为任何JSON对象生成实际的“x-www-form-urlencoded”数据,相当于JQuery。有些接近,但在子项上失败。我从一些解决方案中拼凑出代码,以获得适用于任何JSON对象的有效版本:
function formData (obj) {
return Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(JSON.stringify(obj[k]))).join('&')
}
仅供参考,我不得不将其用于FastSpring的API,因为出于某种奇怪的原因,他们在2020年只接受x-www-form-Url编码的数据。这是近十年来API第一次接受JSON:(这里的大多数解决方案在数组/对象值上失败) 这将支持第一级的数组/对象:
const param = obj => Object.entries(obj).map(
pair => Array.isArray(pair[1]) ?
pair[1].map(x=>`${encodeURIComponent(pair[0])}[]=${encodeURIComponent(x)}`).join('&') :
typeof pair[1] === 'object' ?
Object.entries(pair[1]).map(x=>`${encodeURIComponent(pair[0])}[${x[0]}]=${encodeURIComponent(x[1])}`).join('&') :
pair.map(encodeURIComponent).join('=')).join('&')
示例:
param({a:1,b:'b'})
"a=1&b=b"
param({a:1,b:2,c:[1,2],d:{e:'abc',f:4}});
"a=1&b=2&c[]=1&c[]=2&d[e]=abc&d[f]=4"
param({a:1,b:2,c:[1,2,'"'],d:{e:'a"b[c]',f:4}});
"a=1&b=2&c[]=1&c[]=2&c[]=%22&d[e]=a%22b%5Bc%5D&d[f]=4"
但是,请注意,它在第二级失败(嵌套):
更新:
如果您不需要IE11支持,请使用URLSearchParams
API。请参见error
:
function urlString(params)
{
if (!params)
return '';
const urlParams = new URLSearchParams();
for (const [name, value] of Object.entries(params))
urlParams.append(name, value || '');
return urlParams.toString();
};
感谢Amynut。这正是我所想的,但我想确保我不会错过任何微妙之处,并以最JSic的方式(对Javascript来说就像Pythonic对Python一样)完成它。jquery实现中的一个微妙之处是“return s.join(&”).replace(r20,“+”)。你真的不需要用+符号替换吗?MDN建议这与发布而不是获取有关。嵌套键如何?你需要递归或展平对象。值得一提的是,它不支持数组/对象。
{a:[1,2],b:{c:3}
应转换为a[]=1&a[]=2&b[c]=3而不是a=1,2&b=[object object]
我发现这是一个很好的解决方案:或者object.entries(obj).map(pair=>pair.map(encodeURIComponent.join('=')).join('&'))
awesome@Albin,但要注意这些es的新功能的兼容性,祝你好运:-DSure!使用Polyfill实现兼容性。例如Polyfill.io就可以解决这个问题。谢谢你的修改。我发现@amaynut的代码更容易阅读。在我看来,一行代码并不总是表示简化。值得一提的是,它不支持数组/对象。{a:[1,2],b:{c:3}
应该转换为a[]=1&a[]=2&b[c]=3
而不是a=1,2&b=[object object]
请添加关于上述代码如何帮助的解释。谢谢,这段代码帮助了我;ES6的真正解决方案
const param = obj => Object.entries(obj).map(
pair => Array.isArray(pair[1]) ?
pair[1].map(x=>`${encodeURIComponent(pair[0])}[]=${encodeURIComponent(x)}`).join('&') :
typeof pair[1] === 'object' ?
Object.entries(pair[1]).map(x=>`${encodeURIComponent(pair[0])}[${x[0]}]=${encodeURIComponent(x[1])}`).join('&') :
pair.map(encodeURIComponent).join('=')).join('&')
param({a:1,b:'b'})
"a=1&b=b"
param({a:1,b:2,c:[1,2],d:{e:'abc',f:4}});
"a=1&b=2&c[]=1&c[]=2&d[e]=abc&d[f]=4"
param({a:1,b:2,c:[1,2,'"'],d:{e:'a"b[c]',f:4}});
"a=1&b=2&c[]=1&c[]=2&c[]=%22&d[e]=a%22b%5Bc%5D&d[f]=4"
param({a:1,b:{c:[1,2]}});
"a=1&b[c]=1%2C2"
function urlString(params)
{
if (!params)
return '';
const urlParams = new URLSearchParams();
for (const [name, value] of Object.entries(params))
urlParams.append(name, value || '');
return urlParams.toString();
};