NestJS 拦截器:无法在传出请求上设置 HTTP 标头

2024-01-02

我正在 NestJS 中编写 API,其中有一组通用标头。我决定使用拦截器将标头附加到传出请求中。标头不会附加到请求中,因此请求不断失败。

拦截器

import * as utils from '../utils/utils';
import {
  CallHandler,
  ExecutionContext,
  Injectable,
  NestInterceptor
} from '@nestjs/common';
import { HEADERS } from '../middlewares/headers.constant';
import { Observable } from 'rxjs';
import { Request } from 'express';
import { DATA_PARTITION_ID } from '../app.constants';

@Injectable()
export class HeadersInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<void> {
    const ctx = context.switchToHttp();
    const request: Request = ctx.getRequest();

    this.setHeaders(request);

    return next.handle();
  }

  private setHeaders(request): void {
    this.updateHeaders(request, HEADERS.ACCEPT, 'application/json');
    this.updateHeaders(request, HEADERS.CONTENT_TYPE, 'application/json');
    this.updateHeaders(request, HEADERS.ACCEPT_ENCODING, 'gzip, deflate, br');
    this.updateHeaders(
      request,
      HEADERS.DATA_PARTITION_ID,
      DATA_PARTITION_ID
    );
    this.updateHeaders(
      request,
      HEADERS.AUTHORIZATION,
      `Bearer ${utils.parseCookies(request).stoken}`
    );
    this.updateHeaders(request, HEADERS.APP_KEY, '');
  }

  private updateHeaders(
    request: Request,
    property: string,
    value: string
  ): void {
    if (!request.headers.hasOwnProperty(property)) {
      request.headers[property] = value;
    } else {
      void 0;
    }
  }
}

该拦截器只做一件事:访问请求并附加标头并将控制权传递给下一个处理程序。

Enums

export enum HEADERS {
  DATA_PARTITION_ID = 'Data-Partition-Id',
  AUTHORIZATION = 'Authorization',
  CONTENT_TYPE = 'Content-Type',
  APP_KEY = 'appkey',
  ACCEPT = 'accept',
  ACCEPT_ENCODING = 'accept-encoding'
}

控制器

import { Body, Controller, Post, Req, UseInterceptors } from '@nestjs/common';
import { HeadersInterceptor } from '../interceptors/headers.interceptor';
import { SearchData } from './models/search-data.model';
import { SearchResults } from './models/search-results.model';
import { SearchService } from './search.service';

@Controller('')
@UseInterceptors(new HeadersInterceptor())
export class SearchController {
  constructor(private searchService: SearchService) {}

  @Post('api/search')
  async searchDataById(@Body() searchData: SearchData, @Req() req): Promise<SearchResults> {
    console.log(req.headers);
    return await this.searchService.getSearchResultsById(searchData);
  }
}

Service

import { HttpService, HttpStatus, Injectable } from '@nestjs/common';
import { AppConfigService } from '../app-config/app-config.service';
import { DataMappingPayload } from './models/data-mapping-payload.model';
import { SearchData } from './models/search-data.model';
import { SearchModelMapper } from './search.service.modelmapper';
import { SearchResults } from './models/search-results.model';
import { ServiceException } from '../exception/service.exception';

@Injectable()
export class SearchService {
  constructor(
    private searchModelMapper: SearchModelMapper,
    private configService: AppConfigService,
    private readonly httpService: HttpService
  ) {}

  async getSearchResultsById(searchData: SearchData): Promise<SearchResults> {
    if (searchData.filters.collectionId) {
      console.log(this.configService.appConfig.urls.SEARCH_RESULTS_BY_COLLECTION_ID_URL.replace(
          '${collectionId}',
          searchData.filters.collectionId
        )
      );
      const searchResultsAPI = await this.httpService
        .get(
          this.configService.appConfig.urls.SEARCH_RESULTS_BY_COLLECTION_ID_URL.replace(
            '${collectionId}',
            searchData.filters.collectionId
          )
        )
        .toPromise();
      const kinds = this.searchModelMapper.getUniqueKinds(
        searchResultsAPI.data.results
      );
      const mappingPayload = await this.getDataMapping(kinds);
      return this.searchModelMapper.generateSearchResults(
        kinds,
        mappingPayload,
        searchResultsAPI.data.results
      );
    } else {
      this.raiseException();
    }
  }

  async getDataMapping(kinds: string[]): Promise<[]> {
    const entityKindNames: DataMappingPayload = {
      entityKindNames: kinds
    };
    const dataMappingAPI = await this.httpService
      .post(
        this.configService.appConfig.urls.DATA_CATALOG_SERVICE_URL,
        JSON.stringify(entityKindNames)
      )
      .toPromise();

    return dataMappingAPI.data.entityViewData;
  }

  // To be moved to util functions
  private raiseException(): void {
    throw new ServiceException(
      {
        message: 'This does not have a collection id',
        missing: 'Collection Id',
        code: HttpStatus.BAD_REQUEST
      },
      HttpStatus.BAD_REQUEST
    );
  }
}

当我访问时req.headers in the 控制器,我确实获得了需要通过拦截器设置的所有标头。

{
[0]   'accept-encoding': 'gzip, deflate, br',
[0]   'accept-language': 'en-US,en;q=0.9',
[0]   cookie: '',
[0]   'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36',
[0]   'content-type': 'application/json',
[0]   accept: 'application/json',
[0]   appkey: '',
[0]   'cache-control': 'no-cache',
[0]   'postman-token': 'cb397012-71aa-460a-b66b-28600538faf9',
[0]   host: 'localhost:8080',
[0]   'content-length': '77',
[0]   connection: 'keep-alive',
[0]   'Data-Partition-Id': 'tenant1',
[0]   Authorization: 'Bearer TOKEN_HERE'
[0] }

当我检查实际请求的日志时,它说授权 is null。这意味着请求不会被拦截,也不会附加标头。

有人遇到过类似的问题吗?


如果我理解正确的话,您希望将标头添加到从HttpService. The interceptor在 NestJS 中工作IncomingMessage(一般传入请求)和ServerResponse(或一般的传出响应)。它看不到从发送的东西HttpService或任何其他 HTTP 客户端。相反,您需要在方法级别或模块级别设置标头(如果它们都是通用值)。这HttpModule has a register and registerAsync方法可用于将值传递给每个HttpService调用,因此如果您有通用标头,您可以通过以下方式管理它们:

@Module({
  imports: [
    HttpModule.register({
      headers: {} // object of headers you want to set
    }),
  ]
})
export class MyModule {}

现在当你使用httpService.get(url)您将随之发送标头。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

NestJS 拦截器:无法在传出请求上设置 HTTP 标头 的相关文章

  • Angular2:setTimeout仅调用一次

    我正在 Angular2 中实现需要使用的功能setTimeout My code public ngAfterViewInit void this authenticate loop private authenticate loop s
  • Redis 客户端忽略其上设置的配置选项并尝试连接到默认 IP 127.0.01

    在AWS中 我使用ElastiCache Redis服务器并使用节点作为后端和 promise redis 包 这就是我尝试连接到我的 redis 服务器端点的方法 client redis createClient host my red
  • 如何从控制器返回 PDF 文件

    我正在尝试使用 NestJs 从控制器端点返回 PDF 文件 未设置时Content typeheader 返回的数据getDocumentFile 很好地返回给用户 然而 当我添加标头时 我得到的返回似乎是某种奇怪形式的 GUID 响应总
  • Typescript 找不到模块

    我在 Typescript 的一个文件 upload ts 中有一个导出的模块 我无法在没有错误的情况下导入到另一个文件 application ts 中 另外 我无法导入 ExpressJS 这是Upload ts
  • 我应该如何在http post请求的请求负载中传递json数据

    我想知道如何在有效负载中传递 json 请求 例如 name test value test var post data var post options host this host path path method POST heade
  • 节点:使用 Nodemailer 的直通流

    我正在使用officegen 生成一个Word 文档 然后计划使用Nodemailer 和Sendgrid 将其附加到电子邮件中 Officegen 输出一个流 但我更愿意将其直接传递到附件 而不是在本地保存 Word 文档然后附加它 Ge
  • 如何使用 Nodejs 创建 Excel 文件?

    我是一名 Nodejs 程序员 现在我有一个数据表 我想将其保存为 Excel 文件格式 我该怎么做呢 我找到了一些 Node 库 但其中大多数是 Excel 解析器而不是 Excel 编写器 我使用的是 Linux 服务器 因此需要一些可
  • TypeScript 中的可变参数方法至少需要一个参数

    我有一个像这样的方法 getValues args Array
  • nodejs mocha suite 未定义错误

    我正在尝试使用摩卡运行一些测试 但似乎无法克服这个错误 E tdd nodejs cart gt mocha cart test js node js 201 throw e process nextTick error or err Re
  • express 或express-generator:我需要两者吗?

    只是探索 Node js 并遇到了 Express 在 npm 存储库站点上https www npmjs com package express https www npmjs com package express它明确指出安装是 np
  • Nextjs 无法在生产环境中的“.next”目录中找到有效的构建

    我正在 docker 中运行我的应用程序 但我的生产构建和启动脚本仅在 docker 环境中失败 虽然node env开发在docker环境下运行良好 这是我的脚本 无法进行生产构建并启动服务器 我正在使用nodemon和babel bui
  • D3、TS 和 Angular 2

    我正在尝试将 D3 v4 与 Angular 2 Typescript 一起使用 我目前正在研究 D3 v4 我能够遵循 stackoverflow 中类似问题的一些答案 但没有成功 我已经导入了大部分 D3 库及其类型 我使用的是 TS
  • 在 Angular html 模板中访问常量枚举

    假设我有一个常量枚举 export const enum MyConstEnum Value1 Value1 Value2 Value2 Value3 Value3 现在我想在我的 Angular 模板中使用它 span This has
  • 护照:登录和帐户注册的不同重定向

    我在我的应用程序中使用护照模块 github身份验证 我想根据操作进行重定向 我检查这是否只是正常登录或者用户是否第一次登录 passport use new GitHubStrategy clientID conf github app
  • Cloud Functions for Firebase - 通过 Nodejs/Cloud Function 将多个 PDF 合并为一个

    我遇到了一个问题 我试图通过云功能合并一堆 PDF 然后将合并的 PDF 下载到用户的计算机上 我的提供程序中有一个函数 它调用云函数并传递指向 pdf 的 URL 数组 如下所示 mergePDFs pdfs Create array o
  • 从回调中访问状态

    我在从回调访问组件状态时遇到问题 国家的价值num更改正确 但此类更改对于加载时定义的回调函数不可见 import React useState from react class MyObject callback gt void cons
  • 使用 AWS CDK 为 lambda 指定自定义角色

    我意识到它很新 但我没有看到任何语言的任何示例 说明如何为使用 AWS CDK 创建的 lambda 指定角色 我正在尝试这样做 const cdk require aws cdk cdk const lambda require aws
  • Docker Compose 无法连接到数据库

    我使用 Nestjs 作为后端 并使用 typeorm 作为 ORM 我尝试在 docker compose 文件中定义我的数据库和应用程序 如果我将数据库作为容器运行 并从本地计算机运行应用程序 那么它运行良好 我的程序连接并创建表等 但
  • 为 Node.js 客户端应用程序保留 Firebase 用户

    我正在使用 Firebase 构建 Node js 命令行界面 CLI 用于与后端进行身份验证 我想避免让用户每次运行命令时都输入密码 相反 我想实现一个 登录 流程 将凭证保留到文件系统 该凭证可用于后续的无密码身份验证 直到用户 注销
  • 如何处理 MongoDB 的断开连接错误

    我在 Node js 进程中看到了这个未捕获的异常 Uncaught exception Error read ETIMEDOUT at TCP onStreamRead internal stream base commons js 16

随机推荐

  • pyqtgraph:缩放时保持 TextItem 的恒定位置

    我想要一个在缩放 y 轴时在图表上保持恒定位置的 TextItem 其功能与图例基本相同 只是作为 TextItem 我可以根据需要更改文本 我不知道该怎么做 欢迎任何建议 这个例子说明了问题 在左侧图表中 缩放 y 轴会导致文本移动 而在
  • Python3.5.2 bdist_wininst:需要Python版本-32,在注册表中找不到

    我在 Windows 7 上使用 Python 3 5 2 32 位创建的包出现问题 我通常使用以下命令在 Windows 上部署 Python 包bdist wininst设置工具的选项 这样 我的同事只需启动 Windows 安装程序
  • 连接两个 mp4 视频后视频中出现奇怪的“暂停”

    我正在连接两个 mp4 视频 问题是第一个视频 intro mp4 持续 5 秒 第二个视频 output mp4 持续 2 秒 连接它们创建的视频持续 9 秒 应该持续 5 2 7 秒 在 Final mp4 视频中 第一个视频 intr
  • 在 WooCommerce 中获取并显示相关产品

    我已将 WooCommerce 相关产品包含在主题中 内容如下 这已被复制到我的模板中并正在执行 然而 尽管我对该产品添加了各种追加销售 related products变量 在循环中使用 为 NULL 为了开始展示这些相关产品 是否还有其
  • ARKit:查找屏幕上SCNNode的坐标

    我有一个简单的 Swift ARKit 设置 其中有一个 SCNNode 和一个在 ARSCNView 中可见的 3D 对象 我想确定该对象在 ARSCNView 上的 2D 坐标 我的意思是对象被绘制到屏幕上时的 x 和 y 坐标 I h
  • 运行较少的服务器端与客户端

    与服务器端相比 在客户端运行 LESS 框架有哪些优点 缺点 如果在客户端运行页面加载时间会受到影响吗 在服务器上 您必须更加小心缓存控制标头 并且会牺牲一点 CPU 能力 在客户端 如果 JS 不可用 它就会中断 对于您的生产系统 在构建
  • 代码辅助 (ctrl+space) 在 Eclipse Kepler 上不起作用 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 Code assist ctrl space doesn t work on Eclipse Kepler This happened t
  • 事件 - 命名约定和风格

    我正在学习 C 中的事件 委托 我可以询问您对我选择的命名 编码风格 摘自 Head First C 一书 的看法吗 明天我要教一个朋友这个问题 并试图想出最优雅的方式来解释这些概念 认为 理解一门学科的最好方法就是尝试并教授它 class
  • SELECT 命令计算百分比

    我试图根据每个视频相对于所有其他视频的观看次数来获取数据库中每个视频的百分比 然后 我尝试显示从最高观看次数到最低观看次数的所有视频 并在一个漂亮的 HTML 页面内的侧面显示其百分比 显然 百分比范围为 0 100 且不会超过 我认为最受
  • 为什么 AutoHotkey 会响应“系统找不到文件”错误?

    我是 AutoHotkey 的新手 无法理解为什么这个脚本给我这个错误 Failed to launch program or document Action
  • 如何使用Gtk.events_pending?

    我有这个基本的 测试 应用程序 我想在其中显示一个旋转器 而它正在长时间运行发射进程 带有数据库请求的函数 让用户知道它不是在调试而是正在启动 我在其他帖子中读到可以这样做Gtk events pending 功能 但我不知道如何 在哪里使
  • Jquery ajax 表单提交包含文件

    我有一个很长的表格 其中包含文件附件 这就是我的表格的样子 表单将提交至此操作 HttpPost public ActionResult AddReceivingConfirm DTOreceiving entry IEnumerable
  • 如何在 Mongoose Schema 中存储 URL 值?

    我正在将图像从 IOS 应用程序上传到 Firebase Firebase 返回元数据 包括 type 的 URLURL 我应该存储它的类型String在数据库中像下面的代码一样 或者有特定类型URLs var schema new Sch
  • 自定义流程 - 委托

    我想知道是否可以实施openiddict与实施的授权类型类似的授权授权类型here https identityserver4 readthedocs io en latest topics extension grants html wi
  • Java Web 服务和 SOAP - 更改元素名称

    我正在编写一个返回自定义类型的 java Web 服务 一切工作正常 除了当我查看 SOAP 响应时它不使用名称 myType 它使用 return 这是我的 SOAP 响应 基本上它说 return 我希望它说 mytype S Enve
  • UnicodeEncodeError:“ascii”编解码器无法对位置 35 中的字符 u'\xc5' 进行编码:序号不在范围内(128)

    我目前正在使用姜戈国家 https github com SmileyChris django countries获取表单字段的 ISO 国家 地区名称列表 它在我的网站上显示没有错误 但在 Django 的管理网站上 由于存在非 ASCI
  • 如何为登录和注销用户显示不同的链接?

    当用户未登录时我试图显示 Support Log In 当他们注销时 它应该说 Support Log Out 这是我试图用来让它工作的代码 div class fr ul class rss li a href Support a li
  • 如何使用 R 从 Excel 中提取 URL 并将其与显示的文本进行匹配?

    我有一个包含大量超链接的 Excel 文件 我想编写一个程序来提取 URL 并将其与显示的文本进行匹配 我可以将包含解决方案的 URL 导入到上一个问题 https stackoverflow com questions 24149821
  • x 轴日期与 nvd3 中的 y 轴数据不一致

    I am using NVD3 with Flask and I have dates on the x axis 正如您所看到的 x 轴上的线与点不重合 我在 x 轴上打印出日 月 年和小时 我不明白为什么日期间隔不相等 即 小时 不相同
  • NestJS 拦截器:无法在传出请求上设置 HTTP 标头

    我正在 NestJS 中编写 API 其中有一组通用标头 我决定使用拦截器将标头附加到传出请求中 标头不会附加到请求中 因此请求不断失败 拦截器 import as utils from utils utils import CallHan