我正在为我的公司设置房屋使用PWA。我应该使用哪种方法将承载令牌附加到来自dom或网络工作者的所有请求。
我使用的此方法在发布form
或json
时可以正常工作,但是我希望使用一种更清洁或更友好的方法,因为我不相信text
后备会足够。
我正在Google的workbox.js服务工作程序模块中寻找一个函数,以查看是否可以将拦截器设置为在对服务器发出请求时始终附加Bearer令牌,因为这将解决我最终遇到的问题首先。该代码基于Firebase Service Worker setup。而且没有任何东西可以获取并重新将帖子数据添加到新请求中,从而有效地删除了整个POST正文。
这是我最终得到的代码。
self.addEventListener( 'fetch', ( event ) => {
const requestProcessor = async ( idToken ) => {
let req = event.request;
// For same origin https requests, append idToken to header.
if ( self.location.origin == getOriginFromUrl( event.request.url ) &&
( self.location.protocol == 'https:' ||
self.location.hostname == 'localhost' ) &&
idToken ) {
let contentType = req.headers.get( "Content-Type" );
// Clone headers as request headers are immutable.
const headers = new Headers();
for ( let entry of req.headers.entries() ) {
headers.append( entry[ 0 ], entry[ 1 ] );
}
// Add ID token to header.
headers.append( 'Authorization', 'Bearer ' + idToken );
try {
let tmpReq = req.clone();
let body = "";
if ( req.body ) {
body = req.body;
} else if ( req.method === "POST" ) {
// get the post data if its json
if ( contentType === "application/json" ) {
// get JSON data
let json = await tmpReq.json();
body = JSON.stringify( json );
// Get the post data if its a submitted form
} else if ( contentType === "application/x-www-form-urlencoded" ) {
// get Form-Data
body = await tmpReq.formData();
// Get the post data as plain text as a fallback
} else {
body = await tmpReq.text();
}
console.log( "Content", content );
}
// create a new request with the Bearer Token and post body
req = new Request( req.url, {
method: req.method,
headers: headers,
mode: 'same-origin',
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
referrer: req.referrer,
body: body,
bodyUsed: req.bodyUsed,
context: req.context
} );
} catch ( e ) {
// This will fail for CORS requests. We just continue with the
// fetch caching logic below and do not pass the ID token.
}
}
return fetch( req );
};
// Fetch the resource after checking for the ID token.
// This can also be integrated with existing logic to serve cached files
// in offline mode.
event.respondWith( getIdToken().then( requestProcessor, requestProcessor ) );
} );
因此,总而言之,我的问题是... 是POST的contentType既不是text()
也不是JSON
覆盖所有角度或应该覆盖的FormData
后备我考虑了一种转移POST正文的新方法。
答案 0 :(得分:1)
如果您要修改Request
,保留body
但使用新的headers
或更新的Request
,最简单的方法是将原始请求作为第一个参数传递给{ {1}}类型为RequestInfo
的构造函数;它可以是字符串URL,也可以是现有的Request
对象。您在第二个参数中输入的RequestInit
类型的任何字段都将覆盖原始响应中的字段。
如果您想添加一个附加的标头值,同时保留所有原始请求的标头,则会有些棘手,因为默认情况下,如果仅在headers
中提供新值,则会覆盖所有标头原始标题。因此,您需要确保将headers
设置为原始标头和新标头的组合。
以下代码说明了这一点:
// This request might be created implicitly by the web app,
// but let's just create it manually as an example:
const originalRequest = new Request('https://example.com', {
body: 'shared body',
method: 'POST',
headers: {
'x-header': 'my header value'
},
});
// Start with the original headers as a baseline:
const modifiedHeaders = new Headers(originalRequest.headers);
// Make any changes you want:
modifiedHeaders.set('Authorization', 'Bearer 12345');
// Create a new request based on the original,
// with the modified headers:
const modifiedRequest = new Request(originalRequest, {
headers: modifiedHeaders,
});
// Everything else in modifiedRequest should be as-is,
// but the headers will be updated.
// Do whatever you want with modifiedRequest at this point.
要注意的一件事是,使用这种方法,当您构造修改后的请求时,原始请求的主体将最终被使用。在您的用例中,这无关紧要,因为只有修改后的请求的body
最终会被读取(当您将其传递给fetch()
时)。如果由于某种原因您确实需要同时阅读两个body
,然后首先在原始请求上调用clone()
,例如
const modifiedRequest = new Request(originalRequest.clone(), {...});
// The two requests now have independent bodies.