Plain Javascript Equivalent of jQuery.param()

2020-06-01 06:29发布

jQuery.param() takes an array of key-value pairs, and turns it into a string you can use as a query string in HTML requests. For example,

a = {
      userid:1,
      gender:male
    }

would get converted to

userid=1&gender=male

I'm trying to call external APIs on the server side in a Google Apps script, which need long query strings. I would use the jQuery param function, but there seems to be no easy way to use jQuery on the server side in Google.

Could you give me plain javascript code that achieves the same functionality?

The jQuery implementation of it is here, but I don't want to take chances skipping over any crucial details by simply copying it and ripping out the code dealing with 'traditional'.

6条回答
再贱就再见
2楼-- · 2020-06-01 07:01
export function param( params ) {
    const p = new URLSearchParams;
    for( const [ key, value ] of Object.entries( params ) ) {
        p.set( key, String( value ) );
    }
    return p.toString();
}
查看更多
叛逆
3楼-- · 2020-06-01 07:15

This was a bit frustrating. None of the solutions here seemed to actually work to produce actual "x-www-form-urlencoded" data for any JSON object, the equivalent of JQuery. Some came close but failed on child items. I pieced code from a few of the solutions to get this, working version for any JSON object:

function formData (obj) {
  return Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(JSON.stringify(obj[k]))).join('&')
}

FYI I had to use this for FastSpring's API, because for some freaky reason they only accept x-www-form-urlencoded data in 2020. Spent all day on this because this is the first time in almost a decade an API didn't just accept JSON :(

查看更多
一夜七次
4楼-- · 2020-06-01 07:17

@Amaynut's answer is awesome. But I do some simplify:

const obj = {
  userid: 1,
  gender: 'male'
}

const params = Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k])).join('&')

or maybe modulize it using es6 module:

util.js

export default {
  params (obj) {
    return Object.keys(obj).map((k) => encodeURIComponent(k) + '=' + encodeURIComponent(obj[k])).join('&')
  }
}

and use like this:

import util from './util'

const q = {
  userid: 1,
  gender: 'male'
}

const query = util.params(q)

console.log(query)
查看更多
Rolldiameter
5楼-- · 2020-06-01 07:20
ES6 gives us some nice primitives:

    // Function that parses an object of string key/value params to build up
    // a string of url params
    // requires an object with no nested values
    export function parseUrlParams(urlParams) {
        const joinByEquals = (pair) => pair.join('=')
        const params = Object.entries(urlParams).map(joinByEquals).join('&')
        if (params) {
            return `?${params}`
        } else {
        return ''
        }
    }

See it in action here: https://www.webpackbin.com/bins/-KnpOI6hb1AzTDpN3wS7

查看更多
乱世女痞
6楼-- · 2020-06-01 07:21

You can also do that with pure JavaScript, but you have to write more lines of code. Try this:

HTML code for testing:

<p id="test"></p>

JavaScript to be fired onload:

a = {
      userid:1,
      gender: "male",
    }

url = Object.keys(a).map(function(k) {
    return encodeURIComponent(k) + '=' + encodeURIComponent(a[k])
}).join('&')

document.getElementById("test").innerHTML=url

The output is this:

userid=1&gender=male

You can try this on JSFIDDLE.NET, it works, here's the link: http://jsfiddle.net/ert93wbp/

查看更多
Anthone
7楼-- · 2020-06-01 07:22

ES6 version that allows to convert nested objects and arrays just use like encodeURI(getUrlString({a: 1, b: [true, 12.3, "string"]})).

getUrlString (params, keys = [], isArray = false) {
  const p = Object.keys(params).map(key => {
    let val = params[key]

    if ("[object Object]" === Object.prototype.toString.call(val) || Array.isArray(val)) {
      if (Array.isArray(params)) {
        keys.push("")
      } else {
        keys.push(key)
      }
      return getUrlString(val, keys, Array.isArray(val))
    } else {
      let tKey = key

      if (keys.length > 0) {
        const tKeys = isArray ? keys : [...keys, key]
        tKey = tKeys.reduce((str, k) => { return "" === str ? k : `${str}[${k}]` }, "")
      }
      if (isArray) {
        return `${ tKey }[]=${ val }`
      } else {
        return `${ tKey }=${ val }`
      }

    }
  }).join('&')

  keys.pop()
  return p
}
查看更多
登录 后发表回答