使用Fetch GET请求设置查询字符串

myl*_*scc 103 javascript fetch-api

我正在尝试使用新的Fetch API:https://developer.mozilla.org/en/docs/Web/API/Fetch_API

我正在做这样的GET请求:

var request = new Request({
  url: 'http://myapi.com/orders',
  method: 'GET'
});
fetch(request);
Run Code Online (Sandbox Code Playgroud)

但是,我不确定如何将查询字符串添加到GET请求.理想情况下,我希望能够向以下URL发出GET请求:

'http://myapi.com/orders?order_id=1'
Run Code Online (Sandbox Code Playgroud)

在jQuery中,我可以通过传递做到这一点{order_id: 1}作为data参数$.ajax().使用新的Fetch API有没有相同的方法呢?

Sco*_*son 191

简洁、现代的方法:

fetch('https://example.com?' + new URLSearchParams({
    foo: 'value',
    bar: 2,
}))
Run Code Online (Sandbox Code Playgroud)

URLSearchParams 的toString() 函数会将查询参数转换为可以附加到 URL 的字符串。在此示例中,当与 URL 连接时,会隐式调用 toString()。您可能希望显式调用 toString() 来显示您的意图。


IE 不支持 URLSearchParams(或 fetch),但有可用polyfills

如果使用 node,您可以通过node-fetch 之类的包添加 fetch API 。URLSearchParams 带有节点,从版本 10 开始可以作为全局对象找到。在旧版本中,您可以在require('url').URLSearchParams.

如果你同时使用 node 和 typescript,你会发现,由于一些技术限制,typescript 不提供全局 URLSearchParams 的类型定义。最简单的解决方法是从 URL 模块导入它。请参阅此处了解更多信息。

  • 感谢分享。我认为这应该被接受的答案。要求将参数传递给 fetch API,虽然这是不可能的,但这个答案非常接近结构中的样子。 (7认同)
  • 请注意,使用打字稿时,您必须仅使用字符串作为值。所以 `bar: 2` 应该是 `bar: '2'`。 (7认同)
  • 更简洁的方法是使用字符串插值: ``` `https://example.com?${new URLSearchParams({foo: 'value'})}` ``` https://developer.mozilla。 org/en-US/docs/Web/JavaScript/Reference/Template_literals (5认同)
  • @jymbob 要具有多个值,您必须在 URLSearchParams 上使用 .append() 方法。例如 `s = new URLSearchParams({foo: 'bar'}); s.append('foo', 'baz'); s.toString()`。或者,构造函数可以采用列表的列表而不是对象。`new URLSearchParams([['foo', 'bar'], ['foo', 'baz']]).toString()` 有关更多使用信息,请参阅文档页面:https://developer.mozilla.org/ en-US/docs/Web/API/URLSearchParams (2认同)

Cod*_*gue 129

2017年3月更新:

URL.searchParams支持已正式登陆Chrome 51,但其他浏览器仍需要polyfill.


使用查询参数的官方方法是将它们添加到URL中.从规范来看,这是一个例子:

var url = new URL("https://geo.example.org/api"),
    params = {lat:35.696233, long:139.570431}
Object.keys(params).forEach(key => url.searchParams.append(key, params[key]))
fetch(url).then(/* … */)
Run Code Online (Sandbox Code Playgroud)

但是,我不确定Chrome是否支持searchParams网址的属性(在撰写本文时),因此您可能希望使用第三方库自己动手解决方案.

2018年4月更新:

通过使用URLSearchParams构造函数,您可以分配一个2D数组或一个对象,然后将其分配给url.search而不是循环遍历所有键并附加它们

var url = new URL('https://sl.se')

var params = {lat:35.696233, long:139.570431} // or:
var params = [['lat', '35.696233'], ['long', '139.570431']]

url.search = new URLSearchParams(params).toString();

fetch(url)
Run Code Online (Sandbox Code Playgroud)

旁注:URLSearchParams也可在NodeJS中使用

const { URL, URLSearchParams } = require('url');
Run Code Online (Sandbox Code Playgroud)

  • `new URLSearchParams` 似乎不能与 `Array` 属性一起正常工作。我希望它将属性 `array: [1, 2]` 转换为 `array[]=1&array[]=2`,但将其转换为 `array=1,2`。手动使用它的 `append` 方法确实会导致 `array=1&array=2`,但我必须遍历 params 对象,并且只对数组类型执行此操作,不是很符合人体工程学。 (3认同)

yck*_*art 22

正如已经回答的那样,这对于fetch-API来说是不可能的.但我必须注意:

如果你在node,那就是querystring包裹.它可以字符串化/解析对象/查询字符串:

var querystring = require('querystring')
var data = { key: 'value' }
querystring.stringify(data) // => 'key=value'
Run Code Online (Sandbox Code Playgroud)

...然后将其附加到网址请求.


但是,上述问题是,您始终必须添加问号(?).所以,另一种方法是使用parsenodes url包中的方法,并按如下方式执行:

var url = require('url')
var data = { key: 'value' }
url.format({ query: data }) // => '?key=value'
Run Code Online (Sandbox Code Playgroud)

queryhttps://nodejs.org/api/url.html#url_url_format_urlobj

这是可能的,因为它内部就是这样:

search = obj.search || (
    obj.query && ('?' + (
        typeof(obj.query) === 'object' ?
        querystring.stringify(obj.query) :
        String(obj.query)
    ))
) || ''
Run Code Online (Sandbox Code Playgroud)


Sud*_*han 19

let params = {
  "param1": "value1",
  "param2": "value2"
}

let query = Object.keys(params)
             .map(k => encodeURIComponent(k) + '=' + encodeURIComponent(params[k]))
             .join('&');

let url = 'https:example.com//xyz.com/search?' + query

fetch(url)
  .then(data => data.text())
  .then((text) => {
    console.log('request succeeded with JSON response', text)
  }).catch(function (error) {
    console.log('request failed', error)
  })
Run Code Online (Sandbox Code Playgroud)


Nic*_*rdy 9

URL您可以在您的上设置参数searchParams

const url = new URL('http://myapi.com/orders');
url.searchParams.set('order_id', '1');
fetch(url);
Run Code Online (Sandbox Code Playgroud)

这样做的优点是可以显式构建请求,同时允许原始请求URL采用任何有效格式。


Hir*_*103 7

您可以使用#stringify查询字符串

import { stringify } from 'query-string';

fetch(`https://example.org?${stringify(params)}`)
Run Code Online (Sandbox Code Playgroud)


小智 5

也许这更好:

const withQuery = require('with-query');

fetch(withQuery('https://api.github.com/search/repositories', {
  q: 'query',
  sort: 'stars',
  order: 'asc',
}))
.then(res => res.json())
.then((json) => {
  console.info(json);
})
.catch((err) => {
  console.error(err);
});
Run Code Online (Sandbox Code Playgroud)


Eve*_*ert 5

我知道这是绝对显而易见的,但我觉得值得添加这个作为答案,因为它是最简单的:

const orderId = 1;
fetch('http://myapi.com/orders?order_id=' + orderId);
Run Code Online (Sandbox Code Playgroud)

  • 值得一提的是,这只适用于整数类型。如果您使用字符串,尤其是用户提供的字符串(如搜索条件),则必须对字符串进行转义,否则如果字符串中出现诸如 `/`、`+` 或 `&` 之类的字符,则会得到奇怪的结果。 (11认同)

Cha*_*kal 5

encodeQueryString —将对象编码为querystring参数

/**
 * Encode an object as url query string parameters
 * - includes the leading "?" prefix
 * - example input — {key: "value", alpha: "beta"}
 * - example output — output "?key=value&alpha=beta"
 * - returns empty string when given an empty object
 */
function encodeQueryString(params) {
    const keys = Object.keys(params)
    return keys.length
        ? "?" + keys
            .map(key => encodeURIComponent(key)
                + "=" + encodeURIComponent(params[key]))
            .join("&")
        : ""
}

encodeQueryString({key: "value", alpha: "beta"})
 //> "?key=value&alpha=beta"
Run Code Online (Sandbox Code Playgroud)


小智 5

无需外部包的解决方案

\n

使用 fetch api执行GET请求我研究了这个不需要安装包的解决方案。

\n

这是调用 google 地图 api 的示例

\n
// encode to scape spaces\nconst esc = encodeURIComponent;\nconst url = 'https://maps.googleapis.com/maps/api/geocode/json?';\nconst params = { \n    key: "asdkf\xc3\xb1laskdGE",\n    address: "evergreen avenue",\n    city: "New York"\n};\n// this line takes the params object and builds the query string\nconst query = Object.keys(params).map(k => `${esc(k)}=${esc(params[k])}`).join('&')\nconst res = await fetch(url+query);\nconst googleResponse = await res.json()\n
Run Code Online (Sandbox Code Playgroud)\n

请随意复制此代码并将其粘贴到控制台上以查看其工作原理!

\n

生成的 url 类似于:

\n
https://maps.googleapis.com/maps/api/geocode/json?key=asdkf%C3%B1laskdGE&address=evergreen%20avenue&city=New%20York\n
Run Code Online (Sandbox Code Playgroud)\n

这就是我决定写这篇文章之前一直在寻找的内容,享受吧:D

\n

  • 功能与[Sudharshan 三年半前提供的答案](/a/42078312/4642212) 相同。 (2认同)