मेरे NestJS एप्लिकेशन में नियंत्रक विधियों में से एक को सादे पाठ को अपने शरीर के रूप में लेना है, लेकिन जब भी मैं अनुरोध करने का प्रयास करता हूं, तो पैरामीटर एक खाली वस्तु के रूप में प्राप्त होता है। क्या यह भी संभव है या क्या मुझे उस सिंगल स्ट्रिंग को पास करने के लिए किसी प्रकार का डीटीओ बनाना होगा?

उदाहरण:

@Post()
  myFunction(@Body() id: string) {
    // do something here
  }
9
luna 11 सितंबर 2018, 23:24

6 जवाब

सबसे बढ़िया उत्तर

मैं देखता हूं कि यह प्रश्न काफी पुराना है, लेकिन यह Google में सबसे पहले सूचीबद्ध है, इसलिए मैं यहां उत्तर जोड़ना चाहता हूं।

यदि आप body-parser मिडलवेयर नहीं जोड़ना चाहते हैं (उदाहरण के लिए, आप केवल एकल नियंत्रक विधि में सादा पाठ चाहते हैं), तो आप raw-body (जो आपके नोड_मॉड्यूल में पहले से मौजूद है) का उपयोग कर सकते हैं, कुछ इस तरह :

import * as rawbody from 'raw-body';
import { Controller, Post, Body, Req } from '@nestjs/common';

@Controller('/')
export class IndexController {

  @Post()
  async index(@Body() data, @Req() req) {

    // we have to check req.readable because of raw-body issue #57
    // https://github.com/stream-utils/raw-body/issues/57
    if (req.readable) {
      // body is ignored by NestJS -> get raw body from request
      const raw = await rawbody(req);
      const text = raw.toString().trim();
      console.log('body:', text);

    } else {
      // body is parsed by NestJS
      console.log('data:', data);
    }

    // ...
  }

}

आप नया पैरामीटर डेकोरेटर भी बना सकते हैं

import * as rawbody from 'raw-body';
import { createParamDecorator, HttpException, HttpStatus } from '@nestjs/common';

export const PlainBody = createParamDecorator(async (data, req) => {
  if (req.readable) {
    return (await rawbody(req)).toString().trim();
  }
  throw new HttpException('Body aint text/plain', HttpStatus.INTERNAL_SERVER_ERROR);
});

और इसे पसंद करें

@Post()
async index(@PlainBody() text: string) {
  // ...

(मैंने डेकोरेटर कोड की जांच नहीं की, इसे यहीं टिप्पणी में लिखा है)

28
yumaa 8 जिंदा 2019, 20:24

पोस्ट अनुरोध के शब्दार्थ को हेडर द्वारा निर्धारित किया जाता है जो सामग्री प्रकार को इंगित करता है। यह सुनिश्चित करने का प्रयास करें कि अनुरोध शीर्षलेख में 'टेक्स्ट/सादा' प्रकार है और इसे देखने से मदद मिलती है।

https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST

0
Rich Duncan 12 सितंबर 2018, 16:01

Nest सादे/पाठ के साथ संगत नहीं है और इसके बजाय आपको अपने एक्सप्रेस ऐप में एक बॉडीपार्सर पास करना होगा। कुछ इस तरह का प्रयास करें:

import * as bodyParser from 'body-parser';


async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  app.use(bodyparser({ ...options })) // for plain/text bodies
  await app.listen(3000)
}
bootstrap();

जहां विकल्प https:/ से बनाया गया है /www.npmjs.com/package/body-parser

0
TehWalnut 12 सितंबर 2018, 23:30

@yumaa की उपरोक्त पोस्ट पर जोड़ा जा रहा है

यहाँ NestJS v7.0.8 के साथ काम करने वाला डेकोरेटर है:

import { createParamDecorator, ExecutionContext, BadRequestException } from '@nestjs/common';
import * as rawBody from "raw-body";

export const PlainBody = createParamDecorator(async (_, context: ExecutionContext) => {
    const req = context.switchToHttp().getRequest<import("express").Request>();
    if (!req.readable) { throw new BadRequestException("Invalid body"); }

    const body = (await rawBody(req)).toString("utf8").trim();
    return body;
})
9
DoronG 24 अप्रैल 2020, 22:54

NestJS के हैंडर में रॉ (टेक्स्ट) बॉडी प्राप्त करने पर यह मेरा विचार है:

  1. एप्लिकेशन को preserveRawBodyInRequest के साथ कॉन्फ़िगर करें जैसा कि JSDoc उदाहरण में दिखाया गया है
  2. कच्चे (पाठ) शरीर को पुनः प्राप्त करने के लिए हैंडलर में RawBody डेकोरेटर का उपयोग करें

कच्चा-अनुरोध.सज्जाकार.ts:

import { createParamDecorator, ExecutionContext } from '@nestjs/common';
import { NestExpressApplication } from "@nestjs/platform-express";

import { json, urlencoded } from "express";
import type { Request } from "express";
import type http from "http";

export const HTTP_REQUEST_RAW_BODY = "rawBody";

/**
 * make sure you configure the nest app with <code>preserveRawBodyInRequest</code>
 * @example
 * webhook(@RawBody() rawBody: string): Record<string, unknown> {
 *   return { received: true };
 * }
 * @see preserveRawBodyInRequest
 */
export const RawBody = createParamDecorator(
  async (data: unknown, context: ExecutionContext) => {
    const request = context
      .switchToHttp()
      .getRequest<Request>()
    ;

    if (!(HTTP_REQUEST_RAW_BODY in request)) {
      throw new Error(
        `RawBody not preserved for request in handler: ${context.getClass().name}::${context.getHandler().name}`,
      );
    }

    const rawBody = request[HTTP_REQUEST_RAW_BODY];

    return rawBody;
  },
);

/**
 * @example
 * const app = await NestFactory.create<NestExpressApplication>(
 *   AppModule,
 *   {
 *     bodyParser: false, // it is prerequisite to disable nest's default body parser
 *   },
 * );
 * preserveRawBodyInRequest(
 *   app,
 *   "signature-header",
 * );
 * @param app
 * @param ifRequestContainsHeader
 */
export function preserveRawBodyInRequest(
  app: NestExpressApplication,
  ...ifRequestContainsHeader: string[]
): void {
  const rawBodyBuffer = (
    req: http.IncomingMessage,
    res: http.ServerResponse,
    buf: Buffer,
  ): void => {
    if (
      buf?.length
      && (ifRequestContainsHeader.length === 0
        || ifRequestContainsHeader.some(filterHeader => req.headers[filterHeader])
      )
    ) {
      req[HTTP_REQUEST_RAW_BODY] = buf.toString("utf8");
    }
  };

  app.use(
    urlencoded(
      {
        verify: rawBodyBuffer,
        extended: true,
      },
    ),
  );
  app.use(
    json(
      {
        verify: rawBodyBuffer,
      },
    ),
  );
}
0
kaznovac 24 नवम्बर 2020, 04:56

पुराना प्रश्न लेकिन उपरोक्त में से किसी ने भी मेरे लिए काम नहीं किया लेकिन निम्नलिखित ने किया:

उपरोक्त डेकोरेटर या नियंत्रक-विधि दृष्टिकोण मेरे लिए काम नहीं करते थे क्योंकि अनुरोध बॉडी बफर हमेशा पहले ही पढ़ा जा चुका था।

मैं निम्नलिखित मिडलवेयर का उपयोग करके इसे काम करने में सक्षम था। (मेरे मामले में ध्यान दें कि मुझे एक ज़ीरो वेबहुक को मान्य करने की आवश्यकता है ताकि उदाहरण उसी की ओर तैयार हो)

Cache-raw-body-on-request.ts:

import { json } from 'body-parser';
import * as cloneBuffer from 'clone-buffer';

export const cachedRawBodyRequestKey = 'rawBodyBuffer';

/**
 * Clones the request buffer and stores it on the request object for reading later 
 */
export const cacheRawBodyOnRequest = json({
  verify: (req: any, res, buf, encoding) => {

    // only clone the buffer if we're receiving a Xero webhook request
    if (req.headers['x-xero-signature'] && Buffer.isBuffer(buf)) {
      req[cachedRawBodyRequestKey] = cloneBuffer(buf);
    }
    return true;
  },
});

मुख्य टीएस:

app.use(cacheRawBodyOnRequest);

नियंत्रक:

const textBody = req[cachedRawBodyRequestKey].toString('utf-8');
0
Max Mumford 8 नवम्बर 2020, 15:21