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

我正在尝试使用新的获取API:

我像这样发出GET请求:

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

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

'http://myapi.com/orders?order_id=1'

jQuery中,我可以通过传递{order_id: 1}作为$.ajax()data参数来实现这一点。对于新的Fetch API是否有等效的方法来做到这一点?

505360 次浏览

2017年3月更新:

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


官方处理查询参数的方法只是将它们添加到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(/* … */)

然而,我不确定Chrome支持URL的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)

旁注:URLSearchParams在NodeJS中也可用

const { URL, URLSearchParams } = require('url');

如上所述,这在fetch-API中是不可能实现的。但我必须指出:

如果你在node上,有querystring包。它可以stringify/解析对象/查询字符串:

var querystring = require('querystring')
var data = { key: 'value' }
querystring.stringify(data) // => 'key=value'

...然后把它附加到url请求。


然而,上面的问题是,你总是必须在前面加上一个问号(?)。因此,另一种方法是使用节点url包中的parse方法,并如下所示:

var url = require('url')
var data = { key: 'value' }
url.format({ query: data }) // => '?key=value'

参见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)
))
) || ''
let params = {
"param1": "value1",
"param2": "value2"
};


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


let url = 'https://example.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)
});

也许这样更好:

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);
});

我知道这是非常明显的陈述,但我觉得有必要加上这个作为答案,因为它是所有答案中最简单的:

const orderId = 1;
fetch('http://myapi.com/orders?order_id=' + orderId);

模板文字在这里也是一个有效的选项,并提供了一些好处。

你可以包括原始字符串,数字,布尔值等:

    let request = new Request(`https://example.com/?name=${'Patrick'}&number=${1}`);

你可以包含变量:

    let request = new Request(`https://example.com/?name=${nameParam}`);

你可以包括逻辑和函数:

    let request = new Request(`https://example.com/?name=${nameParam !== undefined ? nameParam : getDefaultName() }`);

至于构造较大查询字符串的数据,我喜欢使用连接到字符串的数组。我发现它比其他一些方法更容易理解:

let queryString = [
`param1=${getParam(1)}`,
`param2=${getParam(2)}`,
`param3=${getParam(3)}`,
].join('&');


let request = new Request(`https://example.com/?${queryString}`, {
method: 'GET'
});

encodeQueryString -将对象编码为查询字符串参数

/**
* 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"

你可以从查询字符串中使用stringify

import { stringify } from 'query-string';


fetch(`https://example.org?${stringify(params)}`)

简洁、现代的方法:

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

工作原理:当字符串(例如URL)与URLSearchParams的实例连接时,它的toString ()方法将自动被调用,以将实例转换为字符串表示,这恰好是一个正确编码的查询字符串。如果自动调用toString()对你来说太神奇了,你可能更喜欢这样显式地调用它:fetch('https://...' + new URLSearchParams(...).toString())

一个带查询参数的获取请求的完整示例:

// Real example you can copy-paste and play with.
// jsonplaceholder.typicode.com provides a dummy rest-api
// for this sort of purpose.
async function doAsyncTask() {
const url = (
'https://jsonplaceholder.typicode.com/comments?' +
new URLSearchParams({ postId: 1 }).toString()
);


const result = await fetch(url)
.then(response => response.json());


console.log('Fetched from: ' + url);
console.log(result);
}


doAsyncTask();


如果您正在使用/支持……

  • Internet Explorer不提供对URLSearchParams或fetch的本地支持,但是有polyfills 可用

  • 从节点18开始,就有了对fetch API的原生支持(在17.5版本中,它位于--experimental-fetch标志后面)。在旧版本中,你可以通过类似node-fetch的包添加获取API。URLSearchParams随Node一起提供,并且从版本10开始可以作为全局对象找到。在旧版本中,你可以在require('url').URLSearchParams找到它。

  • 如果你同时使用Node和TypeScript,你会发现,由于一些技术限制,TypeScript不提供全局URLSearchParams的类型定义。最简单的解决方法是从url模块导入它。更多信息见在这里

刚刚与Nativescript的fetchModule一起工作,并使用字符串操作找出了我自己的解决方案。 将查询字符串逐位附加到url。下面是一个例子,query作为json对象传递(query = {order_id: 1}):

function performGetHttpRequest(fetchLink='http://myapi.com/orders', query=null) {
if(query) {
fetchLink += '?';
let count = 0;
const queryLength = Object.keys(query).length;
for(let key in query) {
fetchLink += key+'='+query[key];
fetchLink += (count < queryLength) ? '&' : '';
count++;
}
}
// link becomes: 'http://myapi.com/orders?order_id=1'
// Then, use fetch as in MDN and simply pass this fetchLink as the url.
}

我在多个查询参数上测试了这个,它像一个咒语一样工作:)

.

.

var paramsdate = 1 + ' % s ' + 12 + ' % s ' + 2012 + ' % s ';

request.get(“https://www.exampleurl.com?fromDate=”+ paramsDate;

没有外部包的解决方案

使用取回api执行得到请求,我在这个解决方案中工作,不需要安装包。

这是一个调用谷歌的映射API的例子

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

请随意复制这段代码并将其粘贴到控制台上,看看它是如何工作的!!

生成的url是这样的:

https://maps.googleapis.com/maps/api/geocode/json?key=asdkf%C3%B1laskdGE&address=evergreen%20avenue&city=New%20York

这是我在决定写这篇文章之前所看到的,喜欢:D