向请求添加新标头,同时保留正文

2024-03-03

我正在为我的公司建立一个内部使用的 PWA。我应该使用什么方法将不记名令牌附加到来自 dom 或 web-worker 的所有请求。

我在发布时使用的这种方法可以按预期工作form or json但我想要一种更干净或更友好的方法,因为我不相信text后备就足够了。

我正在 Google 的 workbox.js 服务工作模块中寻找一个函数,看看我是否可以设置一个拦截,以便在向我的服务器发出请求时始终附加不记名令牌,因为这将解决为什么我首先在​​这里结束的问题地方。该代码基于Firebase Service Worker 设置 https://firebase.google.com/docs/auth/web/service-worker-sessions?authuser=0。并且没有任何东西可以获取并将 post 数据重新添加到新请求中,从而有效地删除整个 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 ) );
} );

总而言之,我的问题是......Is the text()当 POST 的 contentType 都不是时我添加的后备JSON or FormData要覆盖所有角度还是我应该考虑一种传输 POST 正文的新方法.


如果你想修改一个Request,保留body但有新的或更新的headers,最简单的方法是将原始请求作为第一个参数传递给Request构造函数,其类型为RequestInfo https://fetch.spec.whatwg.org/#requestinfo;它可以是字符串 URL,也可以是现有的Request目的。您在第二个参数中指定的任何字段,其类型为RequestInit https://fetch.spec.whatwg.org/#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())。如果由于某种原因,您确实需要阅读这两篇文章bodys,然后调用clone()首先根据原始请求,例如

const modifiedRequest = new Request(originalRequest.clone(), {...});
// The two requests now have independent bodies.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

向请求添加新标头,同时保留正文 的相关文章

  • Python Selenium:如何在文本文件中打印网站上的值?

    我正在尝试编写一个脚本 该脚本将从 tulsaspca org 网站获取以下 6 个值并将其打印在 txt 文件中 最终输出应该是 905 4896 7105 23194 1004 42000 放置的动物 的 HTML span class
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 如何在发布期间复制未版本化的测试资源:执行?

    我的问题与 Maven 在发布时不会复制未跟踪的资源 https stackoverflow com questions 10378708 maven doesnt copy untracked resources while releas
  • CFdump cfcomponent cfscript

    可以在 cfcomponent 中使用 cfdump 吗 可以在 cfscript 中使用 cfdump 吗 我知道 anser 不是 那么如何发出 insde cfcomponent 函数的值 cf脚本 我用的是CF8 可以在 cfcom
  • 如何确定所有角度2分量都已渲染?

    当所有 Angular2 组件完成渲染时 是否会触发一个角度事件 For jQuery 我们可以用 function 然而 对于 Angular2 当domready事件被触发 html 只包含角度组件标签 每个组件完成渲染后 domrea
  • 如何在执行新操作时取消先前操作的执行?

    我有一个动作创建器 它会进行昂贵的计算 并在每次用户输入内容时调度一个动作 基本上是实时更新 但是 如果用户输入多个内容 我不希望之前昂贵的计算完全运行 理想情况下 我希望能够取消执行先前的计算并只执行当前的计算 没有内置功能可以取消Pro
  • 如何从日期中查找该月的最后一天?

    如何在 PHP 中获取该月的最后一天 Given a date 2009 11 23 我要2009 11 30 并给出 a date 2009 12 23 我要2009年12月31日 t返回给定日期所在月份的天数 请参阅的文档date ht
  • PHPUnit 和 Zend Framework assertRedirectTo() 问题

    我在创建的测试中遇到了 assertRedirectTo 问题 下面是我使用的代码 public function testLoggedInIndexAction this gt dispatch this gt assertControl
  • 如何使用asm.js进行测试和开发?

    最近我读到asm js规范 看起来很酷 但是是否有任何环境 工具来开发和测试这个工具 这还只是处于规范阶段吗 您可以尝试使用 emscripten 和 ASM JS 1 并从侧分支在 firefox 构建中运行它 有关 asm js 的链接
  • Vue.js[vuex] 如何从突变中调度?

    我有一个要应用于 json 对象的过滤器列表 我的突变看起来像这样 const mutations setStars state payload state stars payload this dispatch filter setRev
  • CSS溢出文本显示在几行中,没有断字

    我有一些长文本显示在 div 中 该 div 具有固定的宽度和高度 我希望文本显示在几行上 作为 div 高度 并且句子单词不会中断 一行中的单词前缀和下一行中的继续 此外 我想在末尾添加省略号最后一句话 CSS white space n
  • Spring Boot @ConfigurationProperties 不从环境中检索属性

    我正在使用 Spring Boot 1 2 1 并尝试创建一个 ConfigurationProperties带有验证的bean 如下所示 package com sampleapp import java net URL import j
  • 对来自流读取器的过滤数据执行小计

    编辑问题未得到解答 我有一个基于 1 个标准的过滤输出 前 3 个数字是 110 210 或 310 给出 3 个不同的组 从流阅读器控制台 问题已编辑 因为第一个答案是我给出的具体示例的字面解决方案 我使用的实际字符串长度为 450 个
  • 循环内的异步性

    我正在使用 jQuery getJSON 用于从一组实用程序的给定 URL 检索数据的 API 我真的很想找到一种为每个实用程序重用代码 完全相同 的方法 由于循环的执行与 ajax 调用无关 因此我无法找到保留循环值的方法 我知道这个描述
  • rspec 中的模拟方法链

    有一系列方法可以获得user目的 我试图模拟以下内容以返回user in my Factory Girl current user AuthorizeApiRequest call request headers result 我可以模拟该
  • 使用 xpath 和 vtd-xml 以字符串形式获取元素的子节点和文本

    这是我的 XML 的一部分
  • 如何使用 Pycharm 安装 tkinter? [复制]

    这个问题在这里已经有答案了 I used sudo apt get install python3 6 tk而且效果很好 如果我在终端中打开 python Tkinter 就可以工作 但我无法将其安装在我的 Pycharm 项目上 pip
  • Erlang dict的时间复杂度

    我想知道 Erlang OTP 是否dict模块是作为哈希表实现的 在这种情况下它是否能提供这样的性能 平均情况 Search O 1 n k Insert O 1 Delete O 1 n k 最坏的情况下 Search O n Inse
  • Statsmodels.formula.api OLS不显示截距的统计值

    我正在运行以下源代码 import statsmodels formula api as sm Add one column of ones for the intercept term X np append arr np ones 50
  • 在 Nexus 7 2013 上更改方向时 CSS 媒体查询不起作用

    我目前正在我的笔记本电脑 台式电脑和 Nexus 7 2013 上测试 CSS 媒体查询 除了 Nexus 7 之外 它们在台式机和笔记本电脑上都运行良好 当我更改方向时 除非刷新页面 否则样式不会应用 例如 以纵向模式握住设备时 页面正常

随机推荐