【问题标题】:JavaScript Array to URLencodedJavaScript 数组到 URL 编码
【发布时间】:2011-01-11 09:40:37
【问题描述】:

有没有js函数将数组转换为urlencoded? 我完全是新手 n JS...谢谢!...


我的数组是一个键值数组.... 所以,

myData=new Array('id'=>'354313','fname'=>'Henry','lname'=>'Ford');

一样
myData['id']='354313';
myData['fname']='Henry';
myData['lname']='Ford';
myData.join('&'); //returns error, it doesn't work on such array...

有什么办法吗?


哦,对不起... 我有一个这样的数组

var myData=new Array('id'=>'354313','fname'=>'Henry','lname'=>'Ford');

然后我需要将数组转换为:

id=354313&fname=Henry&lname=Ford

【问题讨论】:

  • 您是在谈论 URL 编码数组中的每个字符串还是将它们连接成 URL 查询字符串或..?
  • 网址编码仅适用于字符串。如果您希望将其应用于数组,您首先需要解释您的意思 - 您是否希望将数组连接成单个字符串?您想对单个数组元素进行编码吗?如何对待非字符串数组元素(如对象、函数或其他数组)?编辑您的问题以包含至少一个您希望实现的示例(原始数组,生成的 url 编码字符串)是一个好主意。
  • @theHack 你可以看看我的回答stackoverflow.com/a/65610041/5798934

标签: javascript urlencode


【解决方案1】:

试试这个:

var myData = {'id': '354313', 'fname':'Henry', 'lname': 'Ford'};
var out = [];

for (var key in myData) {
    if (myData.hasOwnProperty(key)) {
        out.push(key + '=' + encodeURIComponent(myData[key]));
    }
}

out.join('&');

如需了解为何使用hasOwnProperty,请查看this answer to "How do I loop through or enumerate a JavaScript object?"

【讨论】:

  • 最好这样做:out.push(key + '=' + encodeURIComponent(arr[key]));
  • 此数据不需要拥有自己的财产
【解决方案2】:

如果你使用 jQuery,可以使用 $.param()。检查here。 使用示例

var myData = {'id' : '354313', 'fname' : 'Henry', 'lname' : 'Ford'};
var url = "https://stackoverflow.com?" + $.param(myData);

输出是

https://stackoverflow.com?id=354313&fname=Henry&lname=Ford

也适用于对象数组(例如来自 jQuery(form).serializeArray()):

var myData = [{'id' : '354313'}, {'fname' : 'Henry'},{'lname' : 'Ford'}];

【讨论】:

    【解决方案3】:

    聚会迟到了,但我提出的这个解决方案可以处理递归和嵌套数组/对象

    function is(className, object) {
        return Object.prototype.toString.call(object) === '[object '+ className +']';
    }
    
    const DataEncoder = function() {
        this.levels = [];
    }
    
    DataEncoder.prototype.__dataEncoding = function(data, actualKey = null) {
        let finalString = '';
        if (actualKey) {
            this.levels.push(actualKey);
        }
    
        const keys = Object.keys(data);
        const l = keys.length;
        for(let a = 0; a < l; a++) {
            const key = keys[a];
            let value = data[key];
    
            if (is('Object', value)) {
                finalString += this.__dataEncoding(value, key);
            } else if (is('Array', value)) {
                const arrValSize = value.length;
                for (let b = 0; b < arrValSize; b++) {
                    let arrVal = value[b];
                    if (actualKey) {
                        finalString += actualKey;
                        for(let c = 1; c < this.levels.length; c++) finalString += '[' + this.levels[c] + ']';
                        if (arrVal === undefined || arrVal === null) arrVal = '';
                        finalString += '[' + key + '][]=' + arrVal + '&';
                    } else {
                        if (arrVal === undefined || arrVal === null) arrVal = '';
                        finalString += key + '[]=' + arrVal + '&';
                    }
                }
            } else {
                if (actualKey) {
                    finalString += this.levels[0];
                    for(let c = 1; c < this.levels.length; c++) finalString += '[' + this.levels[c] + ']';
                    if (value === undefined || value === null) value = '';
                    finalString += '[' + key + ']=' + value + '&';
                } else {
                    if (value === undefined || value === null) value = '';
                    finalString += key + '=' + value + '&';
                }
            }
        }
        this.levels.pop();
        return finalString;
    }
    
    DataEncoder.prototype.encode = function(data) {
        if (!is('Object', data) || data === {}) return null;
        return this.__dataEncoding(data).slice(0, -1);
    }
    

    用法:

    const testData = {
      name: "John",
      age: 13,
      skills: ['games', 'programming', 'reading', 'singing'],
      invests: {
        education: [120.3, 50.5],
        kids: 70,
        optical: {
          north: 20.5,
          south: 10.70,
          west: 6,
          east: [7]
        },
        deeper: {
          first: {
            landing: 5
          }
        }
      }
    };
    const encoder = new DataEncoder();
    encoder.encode(testData);
    

    结果:

    name=John&age=13&skills[]=games&skills[]=programming&skills[]=reading&skills[]=singing&invests[education][]=120.3&invests[education][]=50.5&invests[kids]=70&invests[optical][north]=20.5&invests[optical][south]=10.7&invests[optical][west]=6&optical[optical][east][]=7&invests[deeper][first][landing]=5
    

    我知道它需要encodeURIComponent方法,但是很容易添加


    编辑、改进

    function is(className, object) {
        return Object.prototype.toString.call(object) === '[object '+ className +']';
    }
    
    const DataEncoder = function() {
        this.levels = [];
        this.actualKey = null;
    
    }
    
    DataEncoder.prototype.__dataEncoding = function(data) {
        let uriPart = '';
        const levelsSize = this.levels.length;
        if (levelsSize) {
          uriPart = this.levels[0];
          for(let c = 1; c < levelsSize; c++) {
            uriPart += '[' + this.levels[c] + ']';
          }
        }
        let finalString = '';
        if (is('Object', data)) {
            const keys = Object.keys(data);
            const l = keys.length;
            for(let a = 0; a < l; a++) {
                const key = keys[a];
                let value = data[key];
                this.actualKey = key;
                this.levels.push(this.actualKey);
                finalString += this.__dataEncoding(value);
            }
        } else if (is('Array', data)) {
            if (!this.actualKey) throw new Error("Directly passed array does not work")
            const aSize = data.length;
            for (let b = 0; b < aSize; b++) {
                let aVal = data[b];
                this.levels.push(b);
                finalString += this.__dataEncoding(aVal);
            }
        } else {
            finalString += uriPart + '=' + encodeURIComponent(data) + '&';
        }
        this.levels.pop();
        return finalString;
    }
    
    DataEncoder.prototype.encode = function(data) {
        if (!is('Object', data) || data === {}) return null;
        return this.__dataEncoding(data).slice(0, -1);
    }
    

    现在它可以处理任何深度的嵌套数组/对象,此编辑具有相同的用法

    const testData = {
      name: "John",
      age: 13,
      skills: ['games', 'programming', 'reading', 'singing'],
      invests: {
        education: [120.3, 50.5],
        kids: 70,
        optical: {
          north: 20.5,
          south: 10.70,
          west: 6,
          east: [7]
        },
        deeper: {
          first: {
            landing: 5,
            arrayLike: [
              {
                despite: true,
                superb: 'yes',
                omg: {
                  kiss: ['la'],
                  maybe: {
                    thiss: {
                      wont: {
                        work: 'false'
                      }
                    }
                  }
                },
                incredible: ['lalolanda', 'raidcall', 'phase', [5], [{waw: '@wesome'}]],
              }
            ]
          }
        }
      }
    };
    const encoder = new DataEncoder();
    encoder.encode(testData);
    

    结果:

    name=John&age=13&skills[0]=games&skills[1]=programming&skills[2]=reading&skills[3]=singing&invests[education][0]=120.3&invests[education][1]=50.5&invests[kids]=70&invests[optical][north]=20.5&invests[optical][south]=10.7&invests[optical][west]=6&invests[optical][east][0]=7&invests[deeper][first][landing]=5&invests[deeper][first][arrayLike][0][despite]=true&invests[deeper][first][arrayLike][0][superb]=yes&invests[deeper][first][arrayLike][0][omg][kiss][0]=la&invests[deeper][first][arrayLike][0][omg][maybe][thiss][wont][work]=false&invests[deeper][first][arrayLike][0][incredible][0]=lalolanda&invests[deeper][first][arrayLike][0][incredible][1]=raidcall&invests[deeper][first][arrayLike][0][incredible][2]=phase&invests[deeper][first][arrayLike][0][incredible][3][0]=5&invests[deeper][first][arrayLike][0][incredible][4][0][waw]=%40wesome
    

    【讨论】:

    • 你摇滚!固体溶液!
    • 需要改进才能使用像 ["1","2","3"] 这样的简单数组
    • @meYnot 你只需要发送{data: ["1","2","3"]} 之类的东西就可以了
    • @flopperJ 非常感谢你的朋友 :)
    【解决方案4】:

    你可以这样做:

    var myData = new Array('id=354313', 'fname=Henry', 'lname=Ford');
    var url = myData.join('&');
    

    【讨论】:

    • 我会选择var url = '?' + myData.join('&amp;');
    【解决方案5】:

    如果你使用对象而不是数组,你可以这样做(ES6):

    var myData = {
        id: 354313,
        fname: 'Henry',
        lname: 'Ford',
        url: 'https://es.wikipedia.org/wiki/Henry_Ford',
    };
    
    encodeDataToURL = (data) => {
        return Object
          .keys(data)
          .map(value => `${value}=${encodeURIComponent(data[value])}`)
          .join('&');
     }
    
    console.log(encodeDataToURL(myData));
    

    【讨论】:

      【解决方案6】:
      var myObject = {
        a: {
          one: 1,
          two: 2,
          three: 3
        },
        b: [ 1, 2, 3 ]
      };
      var recursiveEncoded = $.param( myObject );
      var recursiveDecoded = decodeURIComponent( $.param( myObject ) );
      
      alert( recursiveEncoded );
      alert( recursiveDecoded );
      

      recursiveEncoded 和recursiveDecoded 的值报警如下:

      a%5Bone%5D=1&a%5Btwo%5D=2&a%5Bthree%5D=3&b%5B%5D=1&b%5B%5D=2&b%5B%5D=3 a[一]=1&a[二]=2&a[三]=3&b[]=1&b[]=2&b[]=3

      https://api.jquery.com/jQuery.param/

      【讨论】:

        【解决方案7】:

        取自 jgrunds 答案,如果您想扩展数组功能

        Array.prototype.toQueryString = function(){
            var out = new Array();
        
            for(key in this){
                out.push(key + '=' + encodeURIComponent(this[key]));
            }
        
            return out.join('&');
        }
        

        或者如果你想要一个独立的功能

        function arrayToQueryString(array_in){
            var out = new Array();
        
            for(var key in array_in){
                out.push(key + '=' + encodeURIComponent(array_in[key]));
            }
        
            return out.join('&');
        }
        

        【讨论】:

          【解决方案8】:

          查看函数转义和unescape

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2020-09-06
            • 2010-11-09
            • 2014-12-25
            • 2023-02-07
            • 2011-01-07
            • 2015-03-03
            • 2017-11-20
            • 1970-01-01
            相关资源
            最近更新 更多