使用React Native中的Fetch进行带查询字符串的GET请求

64

我正在这样发送请求:

fetch("https://api.parse.com/1/users", {
  method: "GET",
  headers: headers,   
  body: body
})

我该如何传递查询字符串参数?我只需将它们添加到URL中吗?在文档中找不到示例。


7个回答

76

你最初的想法是正确的:只需将它们添加到URL中。

请记住,您可以使用模板字符串(反引号)来简化将变量放入查询中的操作。

const data = {foo:1, bar:2};

fetch(`https://api.parse.com/1/users?foo=${encodeURIComponent(data.foo)}&bar=${encodeURIComponent(data.bar)}`, {
  method: "GET",
  headers: headers,   
})

41

简短回答

只需像这样将数值替换到URL中:

const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);

更详细的回答

是的,您只需要自己将查询字符串添加到URL中。但是,请注意对查询字符串参数进行转义 - 不要仅构造像以下这样的URL:

`https://example.com/foo?bar=${someVariable}`

除非您确信 someVariable 绝对不包含任何特殊字符,如 &= 或其他特殊字符。

如果您在 React Native 之外使用 fetch,则可以使用URLSearchParams对查询字符串参数进行编码。然而,React Native 不支持 URLSearchParams。相反,请使用encodeURIComponent

例如:

const encodedValue = encodeURIComponent(someVariable);
fetch(`https://example.com/foo?bar=${encodedValue}`);

如果您想将键和值的对象序列化为查询字符串,您可以编写一个实用函数来实现:

function objToQueryString(obj) {
  const keyValuePairs = [];
  for (const key in obj) {
    keyValuePairs.push(encodeURIComponent(key) + '=' + encodeURIComponent(obj[key]));
  }
  return keyValuePairs.join('&');
}

...然后像这样使用它:

const queryString = objToQueryString({
    key1: 'somevalue',
    key2: someVariable,
});
fetch(`https://example.com/foo?${queryString}`);

5

这是一种 ES6 的方法。

const getQueryString = (queries) => {
    return Object.keys(queries).reduce((result, key) => {
        return [...result, `${encodeURIComponent(key)}=${encodeURIComponent(queries[key])}`]
    }, []).join('&');
};

在这里我们需要处理一个查询对象,它的形式为key: param。 我们遍历并缩减此对象的键,构建一个编码查询字符串数组。 最后,我们将其连接起来并返回可附加的查询字符串。


虽然我们都知道代码相当简单,但为答案添加一些解释是更好的选择。 - keikai
const data = {city:'Amman', country:'Jordan', month: 7, annual: false};fetch(http://api.aladhan.com/v1/calendarByCity?${getQueryString(data)}, { method: "GET" }) - simo

4

我对Mark Amery的回答进行了小改动,以便符合Airbnb的eslint定义要求,因为很多团队现在都有这个要求。

function objToQueryString(obj) {
  const keyValuePairs = [];
  for (let i = 0; i < Object.keys(obj).length; i += 1) {
    keyValuePairs.push(`${encodeURIComponent(Object.keys(obj)[i])}=${encodeURIComponent(Object.values(obj)[i])}`);
  }
  return keyValuePairs.join('&');
}

2

我处理这个问题的简单函数:

/**
 * Get query string
 *
 * @param   {*}   query   query object (any object that Object.entries() can handle)
 * @returns {string}      query string
 */
function querystring(query = {}) {
  // get array of key value pairs ([[k1, v1], [k2, v2]])
  const qs = Object.entries(query)
    // filter pairs with undefined value
    .filter(pair => pair[1] !== undefined)
    // encode keys and values, remove the value if it is null, but leave the key
    .map(pair => pair.filter(i => i !== null).map(encodeURIComponent).join('='))
    .join('&');

  return qs && '?' + qs;
}

querystring({one: '#@$code', two: undefined, three: null, four: 100, 'fi##@ve': 'text'});
// "?one=%23%40%24code&three&four=100&fi%23%23%40ve=text"
querystring({});
// ""
querystring('one')
// "?0=o&1=n&2=e"
querystring(['one', 2, null, undefined]);
// "?0=one&1=2&2" (edited)

1

是的,你应该这样做。在JS中有一些类可以帮助你,其中一个很方便的是https://developer.mozilla.org/en-US/docs/Web/API/URLSearchParams

例如,如果你有一个JavaScript对象中的参数:

let params = {one: 'one', two: 'two'}

你可以说这个函数。
let queryString = new URLSearchParams()
for(let key in params){
  if(!params.hasOwnkey())continue
  queryString.append(key, params[key])
}

然后,您可以通过以下方式获取格式良好的查询字符串:
queryString.toString()

3
URLSearchParams 在 React Native 中不存在。唯一的使用方法是通过一个 polyfill,而这个答案并没有提到这一点。 - Mark Amery
我认为这个 polyfill 默认已经通过 whatwg-fetch 包含在 React Native 中了,所以 URLSearchParams 应该是安全可用的,至少在 React Native 0.59 版本中是这样的。 - Eliot

0

已接受的答案可行,但如果你有多个参数,它就不太普适了。我建议以下方法,它还可以处理数组参数:

let route = 'http://test.url.com/offices/search';
if (method == 'GET' && params) {
  const query = Object.keys(params)
    .map((k) => {
      if (Array.isArray(params[k])) {
        return params[k]
          .map((val) => `${encodeURIComponent(k)}[]=${encodeURIComponent(val)}`)
          .join('&');
      }

      return `${encodeURIComponent(k)}=${encodeURIComponent(params[k])}`;
    })
    .join('&');

  route += `?${query}`;
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接