Nodejs 5. Express

Zero, article directory

Nodejs 5. Express

1. First introduction to Express

(1) Introduction to Express
  • What is Express

    • Official concept: Express is a fast, open, and minimalist web development framework based on the Node.js platform.

    • Popular understanding: Express functions similarly to the built-in http module of Node.js, which is specially used to create web servers.

    • The essence of Express: It is a third-party package on npm that provides a convenient way to quickly create a web server.

    • Express’s Chinese official website: http://www.expressjs.com.cn/

  • Learn more about Express

    • Thoughts: Is it possible to create a web server without using Express? Answer: Yes, just use the native http module provided by Node.js.
    • Thinking: With the http built-in module, why use Express? Answer: The built-in http module is very complicated to use and the development efficiency is low; Express is further encapsulated based on the built-in http module, which can greatly improve development efficiency.
    • Thinking: What is the relationship between the http built-in module and Express? Answer: Similar to the relationship between Web API and jQuery in the browser. The latter is further encapsulated based on the former.
  • What Express can do

    • Web 网站服务器: A server dedicated to providing external web page resources.
    • API 接口服务器: A server that specifically provides API interfaces to the outside world.
(2) Basic use of Express
  • Install:npm i express
  • Create a basic web server
// 1. 导入 express
const express = require('express')

// 2. 创建 web 服务器
const app = express()

//3.调用app.listen(端口号,启动成功后的回调函数),启动服务器
app.listen(8787, () => {
    
    
    console.log('express server running at http://127.0.0.1:8787')
})
  • **Monitoring GET requests:** Through the app.get() method, you can monitor the client's GET requests. The specific syntax format is as follows:
//参数1:客中端情球的URL地址
//参数2:请求对应的处理函数
//      reg:请求对象(包含了与请求相关的属性与方法)
//      res:响应对像(包含了与响应相关的属性与方法)
app.get('请求URL',function(req,res)(/*处理函数/})
  • **Monitoring POST requests: **Through the app.post() method, you can monitor the client's POST requests. The specific syntax format is as follows:
//参数1:客中端情球的URL地址
//参数2:请求对应的处理函数
//      reg:请求对象(包含了与请求相关的属性与方法)
//      res:响应对象(包含了与响应相关的属性与方法)
app.post('请求URL',function(req,res){
    
    /处理函数/})
  • **Respond the content to the client:**Through the res.send() method, the processed content can be sent to the client:
app.get('/user',(req.res)=>
	//向客户端发送JS0N对象
	res.send(name:'zs'.age:20,gender:))
)
app.post('/user'.(req,res)=>{
    
    
	//向暗户端发送文本内容
	res.send('请求成功')
)
  • ** Get the query parameters carried in the URL: ** Through the req.query object, it can be accessed by the client and sent to the server in the form of 查询字符串 Parameters:
app.get('/',(req.res)=>
	//reg.query默认是一个空对像
	//客户端使用?name=zs&age=20这种查间字符串形式,发送到服务器的参数
	//可以通过reg.query对像访问到,例如:
	//req.query.name req.query.age
	console.log(req.query)
)
  • ** Get the dynamic parameters in the URL: ** Through the req.params object, you can access the URL, and through the : matched 动态参数
//UL地址中,可以通过:参数名的形式,匹配动态参数值
app.get('/user/:id',(req.res)=>
	//reg.params默认是一个空对像
	//里面存放着通过:动态匹配到的参数值
	console.log(req.params)
})
(3) Hosting static resources
  • express.static()

    • express provides a very useful function called express.static(), through which we can create a static resource server very conveniently.
    • For example, you can use the following code to make images, CSS files, and JavaScript files in the public directory accessible to the outside world:
    app.use(express.static('public'))
    
    • Express searches for files in the specified static directory and provides external access paths to resources. Therefore, the name of the directory where the static files are stored will not appear in the URL.
    • Now, you can access all files in the public directory:
      • http://localhost:3000/images/bg.jpg
      • http://localhost:3000/css/style.css
      • http://localhost:3000/js/login.js
  • Host multiple static resource directories

    • If you want to host multiple static resource directories, please多次调用 express.static() 函数.
    • When accessing static resource files, the express.static() function will depend on the directory's 添加顺序查找required files.
app.use(express.static('public'))
app.use(express.static('files'))
  • Mount path prefix

    • If you want to host 静态资源访问路径之前,挂载路径前缀, you can use the following method:
    app.use('/public',express.static('public'))
    
    • You can now access files in the public directory via addresses prefixed with /public:

      • http://localhost:3000/public/images/kitten.jpg

      • http://localhost:3000/public/css/style.css

      • http://localhost:3000/public/js/app.js

(4) nodemon
  • what is nodemon

    • When writing and debugging a Node.js project, if you modify the project code, you need to frequently close it manually and then restart it, which is very cumbersome.
    • Use nodemon (https://www.npmjs.com/package/nodemon), which can monitor changes in project files , when the code is modified, nodemon will automatically help us restart the project, which greatly facilitates development and debugging.
  • Install nodemon

    • In the terminal, run the following command to install nodemon as a globally available tool:

      npm install -g nodemon
      
  • Use nodemon

    • Traditional method:node app.js, after the code is modified, the project needs to be restarted manually.
    • New method:nodemon app.js, after the code is modified, it will be monitored by nodemon, thus achieving the effect of automatically restarting the project.

2. Express routing

(1) Concept of routing
  • What is routing?: Broadly speaking, routing is映射关系.

  • Routing in Express

  • In Express, routing refers to the mapping relationship between 客户端的请求 and 服务器处理函数.

  • The routing in Express is divided into 3 parts, namely请求的类型、请求的 URL 地址、处理函数, and the format is as follows:

app.METHOD(PATH,HANDLER)
  • Express routing case
//匹配GET请球,且清球URL为/
app.get('/',function (req,res){
    
    
	res.send('Hello World!')
)
//匹配POST请球,且请求URL为/
app.post('/',function (req.res){
    
    
	res.send('Got a POST request')
)
  • Route matching process

    • Whenever a request reaches the server,需要先经过路由的匹配, the corresponding processing function will be called only after the match is successful.

    • When is matched, it will be matched according to the route's 顺序进行. If 请求类型 and 请求的 URL are matched successfully at the same time, Express This request will be forwarded to the corresponding function for processing.

    image-20230613104058416

(2) Use of routing
  • The simplest usage: Mount the route directly to the app. The sample code is as follows:
const express require('express')
//创健Web服务器,命名为app
const app express()
//挂载路由
app.get('/',(req,res)>{
    
    res.send('Hello World.'))
app.post('/'.(req.res)>{
    
    res.send('Post Request.')))
//启动Web服务器
app.listen(8787,()=>console.log('server running at http://127.0.0.1:8787')})
  • Modular routing

    • In order to facilitate routing模块化的管理, Express does not recommend mounting routing directly to the app. Instead, it is recommended to extract the route to 单独的模块.
    • The steps to extract routing into a separate module are as follows:
      • Create the .js file corresponding to the routing module
      • Call express.Router() function to create routing object
      • Mount specific routes to routing objects
      • Use module.exports to share routing objects externally
      • Use app.use() function to register routing module
  • Create routing module

    • /router/user.js
var express=require('express')               //1 导入express
var router=express.Router()                  //2 创健路由对象

router.get('user/1ist',function(req,res)(    //3 挂载取用户列表的路由
     res.send('Get user list.')
)

router,post('/user/add',function(req,res){
    
        //4 挂添加用户的路由
    res.send('Add new user.')
})

module.exports=router                         //5 向外导出路由对像
  • Register routing module
//1,导入路由模块
const userRouter=require('./router/user.js')

//2,使用app.use()注册路由模块
app.use(userRouter)
  • For the routing module添加前缀
    • Similar to the unified mounting of access prefixes for static resources when hosting static resources, the way the routing module adds prefixes is also very simple:
//1,导入路由模块
const userRouter=require('./router/user.js')

//2,使用app.use()注册路由模块,并添加统的防问前缀/api
app.use('/api',userRouter)

3. Express middleware

(1)The concept of middleware
  • What is middleware?: Middleware, specifically 业务流程's中间处理环节.

  • Express middleware calling process

    • When a request reaches the Express server, you can连续调用多个中间件 proceed with the request预处理.

image-20230613110523161

  • Express middleware format
    • Express's middleware is essentially afunction 处理函数
    • The formal parameter list of the middleware function must contain the next parameter. The routing processing function only contains req and res.

image-20230613110702660

  • The role of next function
    • next 函数 is the key to realize the continuous calling of multiple middlewares. It means passing the transfer relationship 转交 to the next 中间件 or 路由.

image-20230613111544628

(2) First experience with Express middleware
  • Define middleware functions
    • You can define the simplest middleware function in the following way:
// 定义一个最简单的中间件函数
const mw = function(req, res, next) {
    
    
    console.log('这是最简单的中间件函数')

    // 注意:在当前中间件的业务处理完毕后,必须调用next()函数
    // 把流转关系,转交给下一个中间件或路由
    next()
}
  • Globally effective middleware
    • Any request initiated by the client, after reaching the server, 都会触发的中间件, is called 全局生效的中间件.
    • By calling app.use(中间件函数), you can define a globally effective middleware. The sample code is as follows:
// 定义一个最简单的中间件函数
const mw = function(req, res, next) {
    
    
    console.log('这是最简单的中间件函数')
    next()
}

//全局生效的中间件
app.use(mw)
  • Define global middleware简化形式
//全局生效的中间件
app.use(function(req, res, next) {
    
    
    console.log('这是最简单的中间件函数')
    next()
})
  • The role of middleware
    • Among multiple middlewares,share the same copy req and res. Based on this feature, we can unify in the middleware of 上游 and add to the req or res object. >'s middleware or routing. , for use by or 's 自定义属性方法下游

image-20230613134452947

  • Define multiple global middleware
    • You can use app.use() 连续定义多个Global middleware. After the client request reaches the server, it will be called according to the middleware定义的先后顺序 in sequence. The sample code is as follows:
// 定义第一个全局中间件
app.use((req, res, next) => {
    
    
  console.log('调用了第1个全局中间件')
  next()
})
// 定义第二个全局中间件
app.use((req, res, next) => {
    
    
  console.log('调用了第2个全局中间件')
  next()
})

//请求这个路由,会依次触发上述两个全局中间件
app.get('/user', (req, res) => {
    
    
  res.send('User page.')
})
  • Locally effective middleware
    • Do not use The middleware defined by app.use() is called locally effective middleware. The sample code is as follows:
// 定义中间件函数mw1
const mw1 = (req, res, next) => {
    
    
  console.log('调用了局部生效的中间件')
  next()
}

// mw1这个中间件只在"当前路由中生效",这种用法属于"局部生效的中间件"
app.get('/', mw1, (req, res) => {
    
    
  res.send('Home page.')
})

// mw1这个中间件不会影响下面这个路由
app.get('/user', (req, res) => {
    
    
  res.send('User page.')
})
  • Define multiple local middleware
    • can be used in routing in the following two ways等价, 使用多个局部中间件:
// 定义中间件函数mw1
const mw1 = (req, res, next) => {
    
    
  console.log('调用了第一个局部生效的中间件')
  next()
}

// 定义中间件函数mw2
const mw2 = (req, res, next) => {
    
    
  console.log('调用了第二个局部生效的中间件')
  next()
}

// 以下两种写法是"完全等价"的,可根据自己的喜好,选择任意一种方式进行使用
app.get('/', mw1, mw2, (req, res) => {
    
    
  res.send('Home page.')
})
app.get('/', [mw1, mw2], (req, res) => {
    
    
  res.send('Home page.')
})
  • Understand 5 things to note when using middleware
    • Be sure to register the middleware路由之前
    • The request sent by the client can be processed连续调用多个中间件
    • After executing the business code of the middleware,不要忘记调用 next() 函数
    • For防止代码逻辑混乱, do not write additional code after calling the next() function
    • When multiple middlewares are called continuously, between multiple middlewares,共享 req and res objects
(3) Classification of middleware
  • In order to make it easier for everyone to understand and remember the use of middleware, Express officially divides the usage of 常见的中间件 into 5 大类, which are:

    • 应用级别middleware
    • 路由级别middleware
    • 错误级别middleware
    • Express 内置middleware
    • 第三方middleware
  • 应用级别middleware

    • through app.use() or app.get() or app.post() ,绑定到 app 实例上的中间件, shout应用级别的中间件, Example below:
//应用级别的中间件(全局中间件)
app.use((req,res,next)=>
	next()
})

//应用级别的中间件(局部中间件)
app.get('/',mw1,(req,res)=>
	res.send('Home page.')
})
  • 路由级别middleware
    • is bound to the middleware on the express.Router() instance, called 路由级别的中间件. Its usage is no different from application-level middleware. The code example is as follows:
var app=express()
var router=express.Router()

//路由级别的中间件
router.use(function (req,res,next){
    
    
	console.log('Time:'Date.now())
	next()
})

app.use('/',router)
  • 错误级别middleware
    • Function: Specifically used to捕获occur in the entire project异常错误 to prevent the project from abnormal crash.
    • Format: In the function processing function of error level middleware, there must be4 个形参, and the order of formal parameters from front to back is (err, req, res, next).
    • Error level middleware must be registered in所有路由之后!
// 1. 定义路由
app.get('/', (req, res) => {
    
    
  // 1.1 人为的制造错误
  throw new Error('服务器内部发生了错误!')
  res.send('Home page.')
})

// 2. 定义错误级别的中间件,捕获整个项目的异常错误,从而防止程序的崩溃
app.use((err, req, res, next) => {
    
    
  console.log('发生了错误!' + err.message)
  res.send('Error:' + err.message)
})
  • Express内置middleware
    • Starting from Express 4.16.0, Express has built-in 3 commonly used middleware, which greatly improves the development efficiency and experience of Express projects:
      • express.static: Built-in middleware for quickly hosting static resources, such as HTML files, images, CSS styles, etc. (no compatibility)
      • express.json: Parse request body data in JSON format (with compatibility, only available in version 4.16.0+)
      • express.urlencoded: Parse request body data in URL-encoded format (with compatibility, only available in version 4.16.0+)
// 通过 express.json() 这个中间件,解析表单中的 JSON 格式的数据
app.use(express.json())
// 通过 express.urlencoded() 这个中间件,来解析 表单中的 url-encoded 格式的数据
app.use(express.urlencoded({
    
     extended: false }))
  • 第三方middleware
    • It is not officially built into Express, but is a middleware developed by a third party, called third-party middleware. In the project, you can download and configure third-party middleware on demand, thereby improving the development efficiency of the project.
    • For example: in versions before [email protected], the third-party middleware body-parser was often used to parse request body data. The usage steps are as follows:
      • Run npm install body-parser Install middleware
      • Use require import middleware
      • Call app.use() Register and use middleware
// 1. 导入解析表单数据的中间件 body-parser
const parser = require('body-parser')
// 2. 使用 app.use() 注册中间件
app.use(parser.urlencoded({
    
     extended: false }))
(4) Custom middleware
  • Manually simulate a middleware similar to express.urlencoded to parse the form data submitted to the server via POST. The implementation steps are as follows:
    • Define middleware: Use app.use() to define globally effective middleware
    • Listen to the data event of req: In the middleware, you need to listen to the data event of the req object to obtain the data sent by the client to the server. If the amount of data is too large to be sent at once, the client will convert 数据切割后,分批发送到服务器. Therefore, the data event may be triggered multiple times. Each time the data event is triggered, the data obtained is only a part of the complete data, which requires 手动对接收到的数据进行拼接.
    • Listen to the end event of req: After requesting the body data接收完毕, the end event of req will be automatically triggered. Therefore, we can 拿到并处理完整的请求体数据 in the end event of req.
    • Use the querystring module to parse the request body data: Node.js has a built-in querystring 模块 specifically for processing query strings. Through the parse() 函数 provided by this module, you can easily convert 查询字符串, 解析成对象的格式.
    • Mount the parsed data object as req.body:上游's中间件 and 下游's Between a>中间件及路由, shares the same req and res. Therefore, we can mount the parsed data as the custom attribute of req and name it req.body, 供下游使用.
    • **Encapsulate custom middleware as a module: **In order to optimize the structure of the code, we can put the custom middleware function, 封装为独立的模块.

Custom middleware code

// 导入 Node.js 内置的 querystring 模块
const qs = require('querystring')

const bodyParser = (req, res, next) => {
    
    
  // 定义中间件具体的业务逻辑
  // 1. 定义一个 str 字符串,专门用来存储客户端发送过来的请求体数据
  let str = ''
  // 2. 监听 req 的 data 事件
  req.on('data', (chunk) => {
    
    
    str += chunk
  })
  // 3. 监听 req 的 end 事件
  req.on('end', () => {
    
    
    // 在 str 中存放的是完整的请求体数据
    // console.log(str)
    // TODO: 把字符串格式的请求体数据,解析成对象格式
    const body = qs.parse(str)
    req.body = body
    next()
  })
}

module.exports = bodyParser

Reference custom middleware

// 导入 express 模块
const express = require('express')
// 创建 express 的服务器实例
const app = express()

// 1. 导入自己封装的中间件模块
const customBodyParser = require('./14.custom-body-parser')
// 2. 将自定义的中间件函数,注册为全局可用的中间件
app.use(customBodyParser)

app.post('/user', (req, res) => {
    
    
  res.send(req.body)
})

// 调用 app.listen 方法,指定端口号并启动web服务器
app.listen(80, function () {
    
    
  console.log('Express server running at http://127.0.0.1')
})

4. Use Express writing interface

(1) Create a basic server

image-20230613153018099

(2) Create API routing module

image-20230613153046343

(3) Write GET interface

image-20230613153118466

(4) Write POST interface
  • If you want to obtain the request body data of URL-encoded 格式, you must configure middleware app.use(express.urlencoded({ extended: false }))

image-20230613153143933

(5) CORS cross-domain resource sharing
  • Interface cross-domain issues

    • The GET and POST interfaces just written have a serious problem:不支持跨域请求.
    • There are two main solutions to solve the interface cross-domain problem:
      • CORS (mainstream solution, 推荐使用)
      • JSONP (Flawed solution: 只支持 GET 请求)
  • Usecors 中间件to solve cross-domain problems

    • cors is a third-party middleware for Express. By installing and configuring cors middleware, cross-domain problems can be easily solved. The usage steps are as follows:

      • Run npm install cors Install middleware

      • Use const cors = require('cors') import middleware

      • Call before routing app.use(cors()) Configure middleware

  • What is CORS

  • CORS (Cross-Origin Resource Sharing, cross-origin resource sharing) consists of a series of HTTP response headers.These HTTP response headers determine whether the browser prevents cross-domain retrieval of front-end JS code. Resources.

  • The browser's同源安全策略 defaults to preventing web pages from obtaining resources "cross-domain". But if接口服务器配置了 CORS 相关的 HTTP 响应头, then 解除浏览器端的跨域访问限制.

image-20230613154429703

  • Things to note about CORS

    • CORS mainly exists服务器端进行配置. The client browser无须做任何额外的配置 can request the CORS-enabled interface.
    • CORS is available in browsers兼容性. Only browsers that support XMLHttpRequest Level2 can normally access the server interface with CORS enabled (for example: IE10+, Chrome4+, FireFox3.5+).
  • CORS response header - Access-Control-Allow-Origin

    • The response header can carry anAccess-Control-Allow-Origin field, where the value of the origin parameter specifies the permission to access the The external domain URL of the resource. For example:Access-Control-Allow-Origin:<origin>|*
    • For example, the following field value willonly allowrequests from https://www.baidu.com:res.setHeader('Access-Control-Allow-Origin','https://www.baidu.com')
    • If the Access-Control-Allow-Origin field value is specified as a wildcard *, it means that requests from any domain are allowed: res.setHeader('Access-Control-Allow-Origin','*')
  • CORS response headers - Access-Control-Allow-Headers

    • By default, CORS supports 客户端向服务器 sending the following 9 request headers: Accept, Accept-Language, Content-Language, DPR, Downlink , Save-Data, Viewport-Width, Width, Content-Type (the value is limited to one of text/plain, multipart/form-data, application/x-www-form-urlencoded)
    • If the client sends 额外的请求头信息 to the server, it needs to pass Access-Control-Allow-Headers , otherwise this request will fail! 服务器端对额外的请求头进行声明
//允许客户端额外向服务器发送Content-Type请求头和X-Custom-Header请求头
//注意:多个请求头之间使用英文的逗号进行分割
res.setHeader('Access-Control-Allow-Headers','Content-Type,X-Custom-Header')
  • CORS response header - Access-Control-Allow-Methods
    • By default, CORS only supports clients to initiate GET, POST, and HEAD requests.
    • If the client wants to request the server's resources through PUT、DELETE and other methods, it needs to pass Access-Control-Alow-Methods on the server side指明The HTTP methods allowed by the actual request.
//只允许POST、GET、DELETE、HEAD
res.setHeader('Access-Control-Allow-Methods','POST,GET,DELETE,HEAD')
//允许所有的HTTP请求方法
res.setHeader('Access-Control-Allow-Methods','*')
  • Classification of CORS requests

    • simple request

      • 请求方式GET、POST、HEAD One of the three
      • HTTP 头部信息No more than the following fields: no custom header field, Accept, Accept-Language, Content-Language, DPR, Downlink, Save-Data, Viewport-Width, Width, Content-Type (only three values ​​application/x- www-form-urlencoded, multipart/form-data, text/plain)
    • Preflight request

      • 请求方式: Request Method type other than GET, POST, and HEAD
      • Request header:包含自定义头部字段
      • Sent data in application/json format to the server
    • Simple request vs preflight request

      • Characteristics of simple requests: between client and server只会发生一次请求.
      • Characteristics of preflight requests: Two requests will occur between the client and the server,OPTION 预检请求成功之后,才会发起真正的请求.
      • Between the browser and the server正式通信之前, the browser will first send OPTION 请求进行预检 to know whether the server allows the actual request. The server succeeds响应预检请求后,才会发送真正的请求, and carries real data.
(6) JSONP interface
  • JSONP

    • Concept: The browser requests data on the server through the src attribute of the <script> tag, and at the same time, the server returns a function call. This way of requesting data is called JSONP.
    • Features: JSONP 不属于真正的 Ajax 请求, because it does not use the XMLHttpRequest object. JSONP 仅支持 GET 请求, does not support POST, PUT, DELETE and other requests.
    • JSONP related knowledge can be referred tohttps://blog.csdn.net/liyou123456789/article/details/131117361
  • Things to note when creating a JSONP interface

    • If CORS cross-domain resource sharing has been configured in the project, for 防止冲突, 必须在配置 CORS 中间件之前声明 JSONP 的接口. Otherwise, the JSONP interface will be processed as an interface with CORS enabled. The sample code is as follows:
//优先创建JS0NP接口【这个接口不会被处理成CORS接口】
app.get('/api/jsonp',(req,res)={
    
    })

//再配置CORS中间件[后续的所有接口,都会被处理成CORS接口]
app.use(cors())

//这是一个开启了CORS的接
app.get('/api/get',(req,res)=>{
    
    })
  • Steps to implement the JSONP interface

    • 获取Sent by the client回调函数的名字
    • 得到要Via JSONP form发送给客户端的数据
    • Based on the data obtained in the first two steps,拼接出一个函数调用的字符串
    • Respond the string obtained by splicing the previous step to the client's <script> tag for parsing and execution
  • Specific code to implement the JSONP interface

app.get('/api/jsonp', (req, res) => {
    
      
  // 1. 得到函数的名称
  const funcName = req.query.callback
  // 2. 定义要发送到客户端的数据对象
  const data = {
    
     name: 'zs', age: 22 }
  // 3. 拼接出一个函数的调用
  const scriptStr = `${
      
      funcName}(${
      
      JSON.stringify(data)})`
  // 4. 把拼接的字符串,响应给客户端
  res.send(scriptStr)
})
  • Use jQuery to make JSONP requests in web pages
    • Calls the $.ajax() function to provide the configuration options of JSONP
$('#btnJSONP').on('click', function () {
    
    
  $.ajax({
    
    
    type: 'GET',
    url: 'http://127.0.0.1/api/jsonp',
    dataType: 'jsonp',
    success: function (res) {
    
    
      console.log(res)
    },
  })
})
(7) Complete code

master file

// 导入 express
const express = require('express')
// 创建服务器实例
const app = express()

// 配置解析表单数据的中间件
app.use(express.urlencoded({
    
     extended: false }))

// 必须在配置 cors 中间件之前,配置 JSONP 的接口
app.get('/api/jsonp', (req, res) => {
    
    
  // TODO: 定义 JSONP 接口具体的实现过程
  // 1. 得到函数的名称
  const funcName = req.query.callback
  // 2. 定义要发送到客户端的数据对象
  const data = {
    
     name: 'zs', age: 22 }
  // 3. 拼接出一个函数的调用
  const scriptStr = `${
      
      funcName}(${
      
      JSON.stringify(data)})`
  // 4. 把拼接的字符串,响应给客户端
  res.send(scriptStr)
})

// 一定要在路由之前,配置 cors 这个中间件,从而解决接口跨域的问题
const cors = require('cors')
app.use(cors())

// 导入路由模块
const router = require('./16.apiRouter')
// 把路由模块,注册到 app 上
app.use('/api', router)

// 启动服务器
app.listen(80, () => {
    
    
  console.log('express server running at http://127.0.0.1')
})

routing file

const express = require('express')
const router = express.Router()

// 在这里挂载对应的路由
router.get('/get', (req, res) => {
    
    
  // 通过 req.query 获取客户端通过查询字符串,发送到服务器的数据
  const query = req.query
  // 调用 res.send() 方法,向客户端响应处理的结果
  res.send({
    
    
    status: 0, // 0 表示处理成功,1 表示处理失败
    msg: 'GET 请求成功!', // 状态的描述
    data: query, // 需要响应给客户端的数据
  })
})

// 定义 POST 接口
router.post('/post', (req, res) => {
    
    
  // 通过 req.body 获取请求体中包含的 url-encoded 格式的数据
  const body = req.body
  // 调用 res.send() 方法,向客户端响应结果
  res.send({
    
    
    status: 0,
    msg: 'POST 请求成功!',
    data: body,
  })
})

// 定义 DELETE 接口
router.delete('/delete', (req, res) => {
    
    
  res.send({
    
    
    status: 0,
    msg: 'DELETE请求成功',
  })
})

module.exports = router

Front-end cross-domain test page

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script src="https://cdn.staticfile.org/jquery/3.4.1/jquery.min.js"></script>
  </head>
  <body>
    <button id="btnGET">GET</button>
    <button id="btnPOST">POST</button>
    <button id="btnDelete">DELETE</button>
    <button id="btnJSONP">JSONP</button>

    <script>
      $(function () {
      
      
        // 1. 测试GET接口
        $('#btnGET').on('click', function () {
      
      
          $.ajax({
      
      
            type: 'GET',
            url: 'http://127.0.0.1/api/get',
            data: {
      
       name: 'zs', age: 20 },
            success: function (res) {
      
      
              console.log(res)
            },
          })
        })
        // 2. 测试POST接口
        $('#btnPOST').on('click', function () {
      
      
          $.ajax({
      
      
            type: 'POST',
            url: 'http://127.0.0.1/api/post',
            data: {
      
       bookname: '水浒传', author: '施耐庵' },
            success: function (res) {
      
      
              console.log(res)
            },
          })
        })

        // 3. 为删除按钮绑定点击事件处理函数
        $('#btnDelete').on('click', function () {
      
      
          $.ajax({
      
      
            type: 'DELETE',
            url: 'http://127.0.0.1/api/delete',
            success: function (res) {
      
      
              console.log(res)
            },
          })
        })

        // 4. 为 JSONP 按钮绑定点击事件处理函数
        $('#btnJSONP').on('click', function () {
      
      
          $.ajax({
      
      
            type: 'GET',
            url: 'http://127.0.0.1/api/jsonp',
            dataType: 'jsonp',
            success: function (res) {
      
      
              console.log(res)
            },
          })
        })
      })
    </script>
  </body>
</html>

Guess you like

Origin blog.csdn.net/liyou123456789/article/details/131241319