Javascript 如何使用不同的URL复制请求对象?
我正在写一个关于Javascript 如何使用不同的URL复制请求对象?,javascript,fetch-api,Javascript,Fetch Api,我正在写一个关于fetch的包装,我想在发出请求之前向URL添加一些内容,例如识别查询参数。我不知道如何使用与原始URL不同的URL复制给定的请求对象。我的代码如下所示: // My function which tries to modify the URL of the request function addLangParameter(request) { const newUrl = request.url + "?lang=" + lang; return new Re
fetch
的包装,我想在发出请求之前向URL添加一些内容,例如识别查询参数。我不知道如何使用与原始URL不同的URL复制给定的请求
对象。我的代码如下所示:
// My function which tries to modify the URL of the request
function addLangParameter(request) {
const newUrl = request.url + "?lang=" + lang;
return new Request(newUrl, /* not sure what to put here */);
}
// My fetch wrapper
function myFetch(input, init) {
// Normalize the input into a Request object
return Promise.resolve(new Request(input, init))
// Call my modifier function
.then(addLangParameter)
// Make the actual request
.then(request => fetch(request));
}
我尝试将原始请求作为请求
构造函数的第二个参数,如下所示:
function addLangParameter(request) {
const newUrl = request.url + "?lang=" + lang;
return new Request(newUrl, request);
}
它似乎复制了旧请求的大多数属性,但似乎没有保留旧请求的正文。比如说,
const request1 = new Request("/", { method: "POST", body: "test" });
const request2 = new Request("/new", request1);
request2.text().then(body => console.log(body));
我希望记录“test”,但它会记录空字符串,因为正文没有被复制
我是否需要做一些更明确的事情来正确复制所有属性,或者是否有一个好的快捷方式可以为我做一些合理的事情
我使用的是polyfill,但在最新的Chrome浏览器中使用了polyfill和原生的fetch
实现进行了测试。看起来您最好的选择是使用body
接口读取正文,该接口请求实现:
这只能异步完成,因为底层的“consume body”操作总是异步读取并返回承诺。像这样的方法应该会奏效:
const request = new Request('/old', { method: 'GET' });
const bodyP = request.headers.get('Content-Type') ? request.blob() : Promise.resolve(undefined);
const newRequestP =
bodyP.then((body) =>
new Request('/new', {
method: request.method,
headers: request.headers,
body: body,
referrer: request.referrer,
referrerPolicy: request.referrerPolicy,
mode: request.mode,
credentials: request.credentials,
cache: request.cache,
redirect: request.redirect,
integrity: request.integrity,
})
);
这样做之后,newRequestP
将是一个承诺,它将解决您想要的请求。幸运的是,无论如何,fetch是异步的,所以您的包装器不应该受到明显的阻碍
(注意:使用.blob()读取正文)
对于一个没有主体的请求,似乎返回了一个零长度的Blob对象,但是在GET或HEAD请求中指定任何主体,甚至是零长度的主体都是不正确的。我认为检查原始请求是否设置了内容类型
是一个准确的代理,它是否有主体,这是我们真正需要确定的不显示伪代码:显示真实代码。@Mike'Pomax'Kamermans我添加了实际代码。我认为这会使理解实际问题变得更加困难,也许会有所帮助。你的新代码通过在代码本身中显示你对请求对象的使用,而不是更加困难,实际上让你的问题变得显而易见。看起来这在github/fetch polyfill中目前不起作用(这没有适当地设置内容类型
标题),但这在Chrome中非常有效。谢谢!正确的正文
赋值可能是const body=['GET','HEAD']。包括(r.method)?未定义:wait r.blob()
。†MDN声明:“使用GET或HEAD方法的请求不能有正文。”