【问题标题】:JavaScript - Url encoding of Array type parametersJavaScript - 数组类型参数的 URL 编码
【发布时间】:2020-09-06 03:13:06
【问题描述】:

我不知道如何以优雅的方式对数组参数进行 URL 编码,以便将 XHR 请求从我的 Vue.js 客户端发送到我的 Symfony PHP API。

例如我有这个 GET 方法端点:

  • /question/list?subjects={idSubject}

它列出了 Question 实体项,并且可以选择接受参数以按它们过滤结果(在本例中为主题)

想要的应该是:

  • /question/list?subjects[]={idSubject}&subjects[]={idSubject}

我正在使用 Axios for Vue.js 来执行 XHR 请求,并且我创建了一个实现我想要的方法的主类。

由于 get() 方法不支持配置对象中的“数据”属性,我以与 POST 调用相同的方式实现它,然后我对其进行处理以构建所需的 URL。

这是我的 Ajax.js 文件:

const ajaxRequest = (config) => {
    const token = TokenStorage.get()

    config.baseURL = '/ajax'
    if (token) {
        config.headers = {
            'Authorization': 'Bearer ' + token
        }
    }

    return Axios.request(config)
}

const Ajax = {

    get: (endpoint, params = null, config = {}) => {
        const querystring = require('querystring')
        let url = endpoint
        if (Array.isArray(params) && params.length) {
            url += '?' + params.join('&')
        } else if (typeof params === 'object' && params !== null && Object.keys(params).length) {
            url += '?' + querystring.stringify(params)
        }

        config = {
            ...config,
            ...{
                url: url,
                method: 'get'
            }
        }

        return ajaxRequest(config)
    },

    post: (endpoint, params, config = {}) => {
        config = {
            ...config,
            ...{
                url: endpoint,
                method: 'post',
                data: params
            }
    }

        return ajaxRequest(config)
    }
}

我知道我可以通过 POST 传递这些数据,但是为了遵循安静的设计,我想保留 GET 方法,并且可选参数可以作为 GET 参数包含在 URL 中。

【问题讨论】:

    标签: javascript arrays xmlhttprequest axios urlencode


    【解决方案1】:

    如果是我,我会构建一个 JavaScript 数组,然后在其上调用 JSON.stringify()...然后对结果字符串进行 URL 编码并将其作为唯一参数附加...以便您的服务器端解析 JSON处理程序。

    【讨论】:

    • 对不起,但我不知道如何通过 JSON.stringify() 实现这一点,因为它返回了相同的 JSON 对象,但以字符串形式。我有一个像这样的对象: { "subjects": [ { id: 1 }, { id: 2} ] } 所以我需要查询 GET 方法的参数 user 是数组中的 "subjects" 和 foreach 项目获取 id 并加入('&')主题=1&subjects=2 之类的项目。问题是它不像数组那样编码,最后一个主题覆盖了前一个主题。应该是subjects[]=1&subjects[]=2
    • 大多数提供 getParameter("x") 之类的函数并返回值的第 3 方服务器端库都依赖于查询部分填充键=值对集合的约定并使用 Map 类型构造来包含这些对...这意味着解析后,仅保留对映射中值的最后更新...即使您使用 [] 库很可能会认为 [] 是参数的“键”的一部分。您需要找到一个服务器端库,以您想要的方式解析它,或者让您的服务器代码解析整个 URI 字符串本身
    • 继续...折衷方案是我建议的...让参数“subjects”等于“['subject1','subject2','subject3']”。您的服务器端代码仍然需要解析该数组并根据需要分离要使用的各个元素...但至少所有主题都可以轻松地从整个 URI 字符串中检索...
    【解决方案2】:

    我处于类似情况,但我找不到用于此的内置库。

    到目前为止我发现的最优雅的解决方案是添加

    Array.prototype.encodeURI = function(name) {
        prefix = `${name}[]=`;
        return prefix + this.map(o => encodeURI(o)).join(`&${prefix}`);
    }
    

    现在你可以使用它了:

    let subjects = ["First Subject", "Second Subject"];
    let myquery = subjects.encodeURI("subjects")
    console.log(myquery)
    // 'subjects[]=First%20Subject&subjects[]=Second%20Subject'
    

    注意:

    对于空数组(例如:let arr = [];),此方法以 subjects[]= 响应,php 将其读取为具有单个空字符串的数组(例如:print_r($_REQUEST["subjects"]) 打印 Array ( [0] => ))。 我找不到发送空数组 url 编码的标准,你应该在某个地方处理它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-07-02
      • 2020-05-31
      • 1970-01-01
      • 2017-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多