In the last article, we summarized five ways to transfer data over HTTP/HTTPS for web development:

  • url param
  • query
  • form urlencoded
  • form data
  • json

These five approaches cover the vast majority of scenarios in development, and you can easily handle the needs of HTTP/HTTPS data communication.

If you want to be a full stack engineer, you need to be able to write both front-end and back-end code.

So, this article we come to realize the back and forth end code, the whole link through, really master them.

The front end uses AXIos to send requests, and the back end uses Nest.js as a server-side framework.

The preparatory work

The first step is to get the Nest.js server up and running and support apis and static pages.

Creating a CRUD service with Nest.js is very fast, with just a few steps:

  • Install @nest/cli and usenest new xxxCreate a nest. js project,
  • Execute in the root directorynest g resource personQuickly generate cruD code for the Person module
  • npm run startStart the Nest.js service

So a service with the CRUD interface of Person is running, isn’t it very fast?

The service runs like this

Print out what interface is available, you can use postman or browser to test:

The API interface runs, and then supports static resource access:

Main.ts is responsible for starting the IOC container of Nest.js, and useStaticAssets are called to support requests for static resources based on the scaffold-generated code.

async function bootstrap() {
  const app = await NestFactory.create<NestExpressApplication>(AppModule);
  app.useStaticAssets(join(__dirname, '.. '.'public'), { prefix: '/static'});
  await app.listen(3000);
}
bootstrap();
Copy the code

We specify prefix as static and add an HTML to the static file directory public:

<html>
<body>hello</body>
</html>
Copy the code

Restart the service and try using your browser:

API interface and static resource access are supported, next to implement the following five front-end HTTP data transfer methods.

url param

The url param is a parameter in the URL, which is declared in nest.js as the: parameter name, and then injected into the Controller via the @param decorator:

@Controller('api/person')
export class PersonController {
  @Get(':id')
  urlParm(@Param('id') id: string) {
    return `received: id=${id}`; }}Copy the code

The front-end code is a get method with parameters in the URL:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
</head>
<body>
    <script>
        async function urlParam() {
            const res = await axios.get('/api/person/1');
            console.log(res);            
        }
        urlParam();
   </script>
</body>
Copy the code

Start the service, under browser access:

The console prints a message back from the server proving that the server got the data passed through the URL param.

In addition to url param, there are also query methods for passing data through urls:

query

Query is the url? After the string, we need to do URL encode.

In nest. js, fetch it from the @query decorator:

@Controller('api/person')
export class PersonController {
  @Get('find')
  query(@Query('name') name: string.@Query('age') age: number) {
    return `received: name=${name},age=${age}`; }}Copy the code

The front-end code also sends a GET request via AXIos:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
</head>
<body>
    <script>
        async function query() {
            const res = await axios.get('/api/person/find', {
                params: {
                    name: 'light'.age: 20}});console.log(res);            
        }
        query();
   </script>
</body>
</html>
Copy the code

Parameters are specified by Params, axios will do URL encode, you don’t have to do it yourself.

Then test it:

The server successfully accepted the data we passed through query.

The above two methods (URL param and query) are used to pass data through the URL, and the following three methods are used to pass data through the body.

html urlencoded

HTML urlencoded is coded to transmit data through the body, in fact, query strings are placed in the body, so we need to do URL encode:

When received with Nest.js, using the @Body decorator, Nest.js will parse the request Body and inject it into the DTO.

Dto is a data Transfer object, which is used to encapsulate transmitted data:

export class CreatePersonDto {
    name: string;
    age: number;
}
Copy the code
import { CreatePersonDto } from './dto/create-person.dto';

@Controller('api/person')
export class PersonController {
  @Post(a)body(@Body() createPersonDto: CreatePersonDto) {
    return `received: The ${JSON.stringify(createPersonDto)}`}}Copy the code

The front-end code uses POST request, specify content type as Application/X-www-form-urlencoded, use QS to do urlencode:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
    <script src="https://unpkg.com/[email protected]/dist/qs.js"></script>
</head>
<body>
    <script>
        async function formUrlEncoded() {
            const res = await axios.post('/api/person', Qs.stringify({
                name: 'light'.age: 20{}),headers: { 'content-type': 'application/x-www-form-urlencoded'}});console.log(res);  
        }

        formUrlEncoded();
    </script>
</body>
</html>
Copy the code

Under test:

The server successfully receives data. Procedure

In fact, json is more commonly used than form urlencoded:

json

Json specifies that the content-type is application/json, and the content will be transferred as JSON:

The backend code also uses @body to receive, and no changes are required. Form urlencoded and JSON are both body values, and Nest.js is internally differentiated according to content type, using different parsing methods.

@Controller('api/person')
export class PersonController {
  @Post(a)body(@Body() createPersonDto: CreatePersonDto) {
    return `received: The ${JSON.stringify(createPersonDto)}`}}Copy the code

The front-end code uses AXIos to send the POST request. By default, the content type is application/ JSON. You don’t need to manually specify it:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
</head>
<body>
    <script>
        async function json() {
            const res = await axios.post('/api/person', {
                name: 'light'.age: 20
            });
            console.log(res);     
        }
        json();
    </script>
</body>
</html>
Copy the code

Under test:

The server successfully received the data passed through JSON.

Json and Form urlencoded are not suitable for transferring files, and form data is used for transferring files:

form data

Form data is separated by ——– as the content of boundary transmission:

Nex.js parse form data using FilesInterceptor’s interceptor, enable it with the @useInterceptors decorator, and fetch it from @uploadedfiles. Non-file content, again, is retrieved by @body.

import { AnyFilesInterceptor } from '@nestjs/platform-express';
import { CreatePersonDto } from './dto/create-person.dto';

@Controller('api/person')
export class PersonController {
  @Post('file')
  @UseInterceptors(AnyFilesInterceptor())
  body2(@Body() createPersonDto: CreatePersonDto, @UploadedFiles() files: Array<Express.Multer.File>) {
    console.log(files);
    return `received: The ${JSON.stringify(createPersonDto)}`}}Copy the code

The front-end code uses AXIos to send the POST request, specifying the content type as multipart/form-data:

<! DOCTYPEhtml>
<html lang="en">
<head>
    <script src="https://unpkg.com/[email protected]/dist/axios.min.js"></script>
</head>
<body>
    <input id="fileInput" type="file" multiple/>
    <script>
        const fileInput = document.querySelector('#fileInput');

        async function formData() {
            const data = new FormData();
            data.set('name'.'light');
            data.set('age'.20);
            data.set('file1', fileInput.files[0]);
            data.set('file2', fileInput.files[1]);

            const res = await axios.post('/api/person/file', data, {
                headers: { 'content-type': 'multipart/form-data'}});console.log(res);     
        }

        formData();
        fileInput.onchange = formData;
    </script>
</body>
</html>
Copy the code

File input Specifies multiple to select multiple files.

Under test:

The server received name and age:

Go to the server console and take a look:

As you can see, the server successfully received the file we uploaded.

The entire code is uploaded to github: github.com/QuarkGluonP…

conclusion

We use AXIos to send the request, and use Nest.js backend service to realize five HTTP/HTTPS data transmission modes:

The first two are in urls:

  • Url param: The parameter in the URL, which is fetched using @param in nest.js
  • Query: in the URL? The latter string is retrieved using @query in nest.js

The last three are in the body:

  • Form urlencoded: Similar to a Query string, but placed in a body. Nest.js uses @body, and axios needs to specify content Type asapplication/x-www-form-urlencodedAnd do URL encode with QS for data
  • Json: Data in JSON format. Js uses @body to fetch the content type. Axios does not need to specify the content type separately. Axios handles it internally.
  • Form data: —– is used as boundary separated data. It is used to transfer files. In nest.js, use FilesInterceptor and @useInterceptors to enable it. The rest of it is at sign Body. The content type needs to be specified in axiosmultipart/form-dataAnd use a FormData object to encapsulate the transferred content.

These five HTTP/HTTPS ways to transfer data cover most development scenarios, and if you want to move up the full stack, being able to provide these five interfaces is the first thing to do.