preface

I do not know whether you have the same problems as me in the daily development and production of the front end

  1. An Intranet or a specific network used by the company, so you can’t use the internal interface outside the company?
  2. Large screen projects or various presentations to the leader worried about network instability, resulting in page data, Echart charts, etc., can not be displayed?
  3. How to create interface data in real time to ensure the progress of front-end development in the absence of back-end development?

. In fact, the summary is the lack of an interface service that our front-end can control

First look at the effect ~

  • All interfaces of front-end projects that rely on the Intranet environment before node service startup are unavailable

  • After the Node service is started and cached in the Intranet state, you can demonstrate and debug the page in an off-intranet environment

  • With cache, Node service can ensure that there is no need to wait for the query of ⌛️ back-end database when making a request to the service. The interface can always be returned within 10ms, so as to ensure that the interface will not appear incomplete page chart or text display due to waiting for a certain interface

Start writing code by hand

Thinking that

  • Start a Node service with a network environment, save all the requested data in the local JSON file after the request, and then get the interface data from the Node service if there is no network environment or need to separate from the back-end debugging.

Directory to build

Since it is a simple project, I do not use koA, Egg and other frameworks here. Partners who need them can introduce them by themselves

  • To perform firstnpm initInitialize the folder 📁
  • Create a new folderindex.jsAs an entry file, create a new utils folder and those under itstore.jsCreate a new JSON folder and the followingtest.jsonThe simple directory structure is now set up.
├─ ├─ ├─ ├─ download.txt // └─ ├─ download.txt // ├─ ├─ download.txt // └─ ├─ download.txt // ├─ ├─ download.txt //Copy the code
The code
  1. store.js
// const fs = require('fs');
const date = new Date(a)const path = require('path')
const defalutpath = path.resolve(__dirname, '.. /json/test.json')
const { promises: { readFile, writeFile } } = require('fs');
async function getStuff (path = defalutpath) {
  let result = await readFile(path, 'utf8');
  return result
}
async function setStuff (value, path = defalutpath) {
  let result = await writeFile(path, value, 'utf8');
  return result
}
const getJson = ((key, callback) = > {
  getStuff().then(res= > {
    const json = res ? JSON.parse(res) : {}
    // console.log(' read data ', json[key])
    // console.log(json[key])
    if (typeof(json[key]) ! = ="undefined") {
      // console.log(' data available ', json[key])
      callback(json[key])
    } else {
      callback(false)}})})const setJson = ((key, value = {}) = > {
  getStuff().then(res= > {
    const json = res ? JSON.parse(res) : {}
    json[key] = value
    if(json ! = =undefined) {
      setStuff(JSON.stringify(json))
      console.log('Write succeeded')}})})// If necessary, you can also add today's date to the stored key value to ensure the validity of the data. Request again after expiration date
const formatDate = ((date) = > {
  let myyear = date.getFullYear()
  let mymonth = date.getMonth() + 1
  let myweekday = date.getDate()
  if (mymonth < 10) {
    mymonth = "0" + mymonth
  }
  if (myweekday < 10) {
    myweekday = "0" + myweekday
  }
  return myyear + "-" + mymonth + "-" + myweekday
})
const store = {
  getJson,
  setJson
}
module.exports = store
Copy the code
  • getStuffandsetStuffTo asynchronously read and write files to avoid node congestion
  • getJsonandsetJsonIs the logical processing of file reading and writing
  1. index.js
// Load the module
const http = require('http');
const server = new http.Server()
const axios = require('axios');
const store = require('./utils/store')
const md5 = require('md5-node')
// const querystring = require('querystring')
const Url = require('url')
// Define the request header to resolve cross-domain
const headers = {
  "Content-Type": "application/json; charset=UTF-8"."Access-Control-Allow-Origin": "*"."access-control-allow-credentials": "true"
}
// 2
server.on('request'.function (request, response) {
  // What happens after the request is heard
  // The request object contains all contents of the user request message
  // response Response object, used to respond to some data
  // When the server wants to respond to data from the client, it must use a Response object
  // const { method, url, headers } = request;
  // console.log(method, url, headers)
  if(request.url ! = ='/favicon.ico') {
    const index = request.url.indexOf('/mock/') // Mock with the front-end convention
    const reurl = 'http://' + request.url.substr(index + 6)
    // 3. Use method to make different judgments
    if (request.method === 'OPTIONS') { 
      response.writeHead(200, {
        "Access-Control-Allow-Credentials": "true"."Access-Control-Allow-Headers": "authorization,content-type,token"."Access-Control-Allow-Methods": "*"."Access-Control-Allow-Origin": "*"."Access-Control-Expose-Headers": "authorization,content-type,token"."Access-Control-Max-Age": "3600"."Connection": "keep-alive"."Content-Length": "0"."Server": 'openresty / 1.15.8.2'
      })
      // res.write('')
      response.end()
      console.log('options go api... ')}if (request.method === 'GET') {
      store.getJson(reurl, ((res) = > { 
        // console.log('GET-res', res)
        if (res) {// If the cache hits 🎯
          console.log('Get request hit cache 🎯')
          response.writeHead(200, headers)
          response.end(JSON.stringify(res))
        } else {
          console.log('GET request hit send...')
          axios.get(reurl)
            .then(res= > {
              store.setJson(reurl, res.data)
              response.writeHead(200, headers);
              response.end(JSON.stringify(res.data));
            })
            .catch(err= > {
              console.log('geterr', err); }}}})))else {/ / post request
      const newURL = Url.parse(reurl)
      parseJSON(request, response, ((res) = > {
        const key = reurl + md5(res)// Md5 encryption is used for POST requests to ensure parameter independence
        const postData = res
        store.getJson(key, (res= > {
        // Here is the configuration if the request header has token or various custom request headers
          const opheaders = {
            // 'Content-Length': length,
            // 'token': request.headers.token ! == undefined ? request.headers.token : '',
            'Content-Type': 'application/json; charset=UTF-8'

          }
          // store.getJson(reurl)
          if (res) {// If the cache hits 🎯
            console.log('POST request hit cache 🎯')
            response.writeHead(200, headers)
            response.end(JSON.stringify(res))
          } else {
            console.log('Post request hit.... ')
            axios.post(reurl, postData, { headers: opheaders })
              .then(function (res) {
                store.setJson(key, res.data)
                response.writeHead(200, headers);
                response.end(JSON.stringify(res.data));
              })
              .catch(function (err) {
                console.log('posterr', err); }); }}))}))}}})function parseJSON (req, res, next) {
  let data = ' '
  // const length = req.headers['content-length']
  req.on('data'.function (chunk) {
    // Chunk is a binary data by default, and data concatenation is automatically toString
    data += chunk;
  });
  // Register the end event, which is executed once all data is received
  // You can use QueryString to deserialize the URL (parsing the URL to split & and = into key-value pairs) if necessary to get an object
  req.on('end'.function () {
    // console.log(data)
    if (data) {
      data = JSON.parse(data)
    }
    next(data)
  })
}

// 4. Listen to the port and start the service
server.listen(8099.function () {
  console.log("The server is started and accessible at the following address:");
  console.log('http://localhost:8099');
})
Copy the code
  • Install dependenciesaxios,md5-node, the idea of the entry file is very simple, after receiving the request to intercept first/mock/The url after is used asstoreThe key value.
  • If the key value is read from the local JSON, the value is directly returned without requesting the back-end interface. If there is no key value, the back-end interface is requested and the return value is written to the local JSON file, and then returned to the front end.

Service startup and use

  1. npm install supervisor -gInstalling this dependency allows us to service hot updates for easy debugging.

  1. runnpm run hotAt this point the project has started
  2. The front-end service adds the node address to the original address, for example, the original front-end request address is172.16.18.147:8080 / / XXX XXXXThen the front-end AXIOS request is configured as

Service IP http://node: 8099 / mock / 172.16.18.147:8080 / / XXX XXXX

  1. After a normal page interface request, all returned data is saved in a local JSON file

  1. When the service is started, if the request matches the 🎯 cache, the network request is not routed, and the local JSON value is fetched directly

summary

At this point, the functionality of the Node service is basically covered. You can use local caches to display data in future demos or off-site scenarios if you enable node services

After doing this, I thought about doing the electron version of the service, so that I could customize the request header and interface parameters from time to time. This part will be updated next time

This is my Github project address has the need of friends can go to see and then click a star ~


Electron has been updated, and nobody’s watching, so I won’t go into details, okay