koa-router post请求数据验证类处理

最近自己写项目的时候发现每一次请求都要做判断,判断多了代码就很乱。

然后,我写php使用tp5框架的时候,它是可以继承一个验证类来实现验证的,我利用午休事件,大概写了一下。

我首先编写了一个验证类的工具类:

class VerifierUtils{
  //邮箱验证
  static email(str)
  {
    if (str.search(/^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z0-9]+$/) != -1)
    {
      return true;
    }else{
      return false;
    }
  }

  //手机验证
  static phone(str)
  {
    if (!(/^1[3456789]\d{9}$/.test(str)))
    {
      return false;
    }else{
      return true;
    }
  }

}
module.exports = VerifierUtils

接着编写 验证类

const utlis = require('./verifierUtils')
class Verifier {
  check(data) {
    for (let list in this.rules) {
      //验证是否为空
      if (!data[list] && this.rules[list]['require'] == true) {
        return `${list}不能为空!`
        break
      }

      //验证是否有邮箱
      if (data[list] && this.rules[list]['email'] == true) {
        if (!utlis.email(data[list])) {
          return `邮箱格式不正确!`
          break
        }
      }

      //验证最小长度
      if (data[list] && this.rules[list]['min']) {
        if (data[list].length < this.rules[list]['min']) {
          return `${list}不能小于${this.rules[list]['min']}位数!`
          break
        }
      }

      //验证最大长度
      if (data[list] && this.rules[list]['max']) {
        if (data[list].length > this.rules[list]['max']) {
          return `${list}不能大于${this.rules[list]['max']}位数!`
          break
        }
      }

      //验证是否相等
      if (data[list] && this.rules[list]['rePassword']) {
        if (data[this.rules[list]['rePassword']]) {

          if (data[this.rules[list]['rePassword']] != data[list]) {
            return `两次输入不一致!`
            break
          }

        } else {
          return `两次输入不一致!`
          break
        }
      }

    }
    return false
  }
}

module.exports = Verifier

接着我们就可以写类来继承它

比方说:注册类

const Verifier = require('./Verifier')
class Register extends Verifier{
  constructor()
  {
    super()
    this.rules={
      "username":{"require":true,"email":true},
      "password":{"require":true,"min":6,"max":16,"rePassword":"rePassword"},
      "code":{"require":true}
    }
  }
}
module.exports = Register

然后我们就可以在外面使用

router.post("/register",async (ctx,next)=>{
  let req = ctx.request.body
  
  let username = req.username
  let password = req.password
  let rePassword = req.rePassword
  let code = req.code

  let data = {
    username,
    password,
    rePassword,
    code
  }

  let check = (new Reg()).check(data)
  if(check)
  {
    ctx.body={
      code:-1,
      msg:check
    }
    return
  }

}

这样我们如果要验证post数据的话,就直接建一个类来继承Verifier 这个类,来编写规则了。

webpack4 构建vue全家桶

最近使用vue-cli用的人有点傻,所以今天没什么事情干,就自己构建一个vue的全家桶来玩玩。

首先:

# 新建目录,并且进入
mkdir mc-webpack && cd mc-webpack
# 创建 package.json
npm init -y
# 安装 vue 依赖
npm i vue
# 安装 webpack 和 webpack-cli 开发依赖
npm i webpack webpack-cli -D
# 安装 babel
npm i babel-loader @babel/core @babel/preset-env -D
# 安装 loader
npm i vue-loader vue-template-compiler -D
# 安装 html-webpack-plugin
npm i html-webpack-plugin -D
# 安装 clean-webpack-plugin 用来删除生成的文件夹
npm i clean-webpack-plugin --D

运行完上面的命令后应该是一下画面:

{
  "name": "mc-webpack",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {
    "vue": "^2.6.10"
  },
  "devDependencies": {
    "@babel/core": "^7.5.5",
    "@babel/preset-env": "^7.5.5",
    "babel-loader": "^8.0.6",
    "html-webpack-plugin": "^3.2.0",
    "vue-loader": "^15.7.1",
    "vue-template-compiler": "^2.6.10",
    "webpack": "^4.36.1",
    "webpack-cli": "^3.3.6"
  }
}

接着创建

#创建src目录,和进入目录
mkdir src
cd src
#创建App.vue主文件
echo *>App.vue
#创建入口js文件
echo *>index.js
#创建主html文件
echo *>index.html

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>mc-webpack</title>
</head>
<body>
  <div id="app"></div>
</body>
</html>

index.js

import Vue from "vue"
import App from "./App"

//阻止启动生产消息,常用作指令。
Vue.config.productionTip = false

new Vue({
  //简写 render:h=>h(App)
  render:function(createElement)
  {
    return createElement(App)
  }
}).$mount("#app")

App.vue

<template>
  <div class="main">
    {{title}}
  </div>
</template>
<script>
export default {
   data() {
      return {
        title:"Hello world!"
      }
   }
}
</script>
<style>
</style>

接着就是配webpack了 (记得是根目录哦)

echo *>webpack.config.js

输入以下代码

const HtmlWebpackPlugin = require("html-webpack-plugin");
const VueLoaderPlugin = require("vue-loader/lib/plugin");//相关地址:https://vue-loader.vuejs.org/zh/guide/#%E6%89%8B%E5%8A%A8%E8%AE%BE%E7%BD%AE
const { CleanWebpackPlugin } = require("clean-webpack-plugin");
const path = require("path");
module.exports = {
  resolve:{
    //这里设置了 import的时候不用添加的后缀名
    extensions:['*','.js','.vue']
  },
  module:{
    rules:[
      //使用babel加载js exclude为不需要在node_modules目录下查找,增加效率
      {
        test:/\.js$/,
        exclude:/node_modules/,
        use:{
          loader:'babel-loader'
        }
      },
      //使用vue的loader加载vue文件
      {
        test:/\.vue$/,
        loader:'vue-loader'
      }
    ]
  },
  plugins:[
    new VueLoaderPlugin(),
    new HtmlWebpackPlugin({
      minify: { // 压缩HTML文件
        removeComments: true, // 移除HTML中的注释
        collapseWhitespace: true, // 删除空白符与换行符
        minifyCSS: true// 压缩内联css
      },
      //模板html路径 src/index.html
      template:'./src/index.html',
      //输出文件名
      filename:'index.html'
    }),
    //删除生成的文件夹
    new CleanWebpackPlugin()
  ]
}

运行npx webpack

如无问题就会出现此目录

运行下

接着我们来完善它

我们首先引入vue-router 官网:
https://router.vuejs.org/zh/installation.html

安装:

npm install vue-router
#接着 cd src目录 新建router.js文件
echo *>router.js

router.js

import Vue from 'vue'
import VueRouter from 'vue-router'
import Home from '@page/home/home'

Vue.use(VueRouter)

export default new VueRouter({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    }
  ]
})

接着新建pages目录 创建home目录 创建home.vue文件

home.vue文件

<template>
   <div class="main">
      dddd
   </div>
</template>
<script>
export default {
   data() {
      return {
      }
   },
   created()
   {
   },
   mounted()
   {
   }
}
</script>
<style>

</style> 

接着修改webpack.config.js 添加别名

resolve: {
    alias: {
      "@page": path.resolve(__dirname, 'pages/'),
    },
    extensions: ['*', '.js', '.vue']
  },

修改App.vue

<template>
  <div id="app">
    <router-view />
  </div>
</template>

修改index.js

import Vue from "vue"
import App from "./App"
import router from "./router"

//阻止启动生产消息,常用作指令。
Vue.config.productionTip = false

new Vue({
  router,
  //简写 render:h=>h(App)
  render:function(createElement)
  {
    return createElement(App)
  }
}).$mount("#app")

npx webpack 运行

接着安装css和stylus 安装 mini-css-extract-plugin 插件

npm i css-loader style-loader --save-dev
npm i stylus stylus-loader --save-dev

修改webpack配置文件

引入 const MiniCssExtractPlugin = require(‘mini-css-extract-plugin’);

      //加载style
      {
        test: /\.styl/,
        use: [MiniCssExtractPlugin.loader, 'css-loader', 'stylus-loader']
      },
      //加载css
      {
        test: /\.css/,
        use: [MiniCssExtractPlugin.loader, 'css-loader']
      },

plugins添加

//拆分css样式
    new MiniCssExtractPlugin({
      filename: '[name].css',
      chunkFilename: '[id].css'
    })

修改home.vue

<template>
  <div class="main">
    ddd
  </div>
</template>
<script>
export default {
   data() {
      return {
      }
   }
}
</script>
<style lang="stylus">
div.main
  color red
  font-size 12px
</style>

运行

接着安装 加载静态文件模块(这里我只写了图片加载)

#生成文件模块
npm i -D file-loader url-loader
#图片压缩模块 这个模块比较大因为它包里加载了 其他类型的 压缩程序
npm i -D image-webpack-loader

修改webpack.config.js文件 添加到rules下

      //压缩图片
      {
        test: /\.(jpe?g|png|gif)$/,
        loader: 'image-webpack-loader',
        enforce: 'pre'
      },
      //加载图片
      {
        test: /\.(jpe?g|png|gif)$/,
        use: {
          loader: 'url-loader',
          options: {
            limit: 3 * 1024,
            name: 'img/[name].[hash:7].[ext]'
          }
        }
      },

添加别名

'@img': path.resolve(__dirname, 'src/assets/img')

添加目录

修改home.vue

<template>
  <div class="main">
    <img src="~@img/adv.gif" alt="">
  </div>
</template>
<script>
export default {
   data() {
      return {
      }
   }
}
</script>
<style lang="stylus">
div.main
  color red
  font-size 12px
</style>

npx webpack 打包

运行

ok

接着是不是觉得每次修改点东西都要重新运行,接着我们就来解决这个问题

#安装
npm install webpack-dev-server --save-dev

接着修改webpack配置文件

devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 9000,
    hot: true,
    open: true
  },

运行 npx webpack-dev-server

你就会发现自动打开浏览器运行 接着你试着修改 home.vue文件,你就会发现页面发生了改变。

好了到这来是不是以为完了呢?其实还有一个vuex,没有引进来。

npm install vuex --save

在src目录下新建 store.js 文件 内容如下:

import Vue from 'vue'
import Vuex from 'vuex'

Vue.use(Vuex)

export default new Vuex.Store({
  state: {
    name:"测试"
  },
  mutations: {
    setName(state,name)
    {
      state.name = name
    }
  },
  actions: {

  }
})

修改home.vue 文件

<template>
  <div class="main">
    <img src="~@img/adv.gif" alt="">
    ddd
  </div>
</template>
<script>
export default {
   data() {
      return {
      }
   },
   created()
   {
     console.log(this.$store.state.name)
   },
   mounted()
   {
     this.$store.commit("setName","测试1")
     console.log(this.$store.state.name)
   }
}
</script>
<style lang="stylus">
div.main
  color red
  font-size 12px
</style>

修改index.js文件

import Vue from "vue"
import App from "./App"
import router from "./router"
import store from "./store"

//阻止启动生产消息,常用作指令。
Vue.config.productionTip = false

new Vue({
  router,
  store,
  //简写 render:h=>h(App)
  render:function(createElement)
  {
    return createElement(App)
  }
}).$mount("#app")

ok完成

git地址
https://gitee.com/huxierong/zidingyiwebpack4yuvue

用koa来 编写一个简单的docker web管理工具

需要用到的库

npm install koa

npm install koa-router

npm install koa-static

npm install koa-views

npm install ejs

目录结构

server 里

sh 里面

产品描述

通过nodejs 里的 child_process 库里的 exec方法来 操作docker shell脚本

然后显示到前端页面上

看一下效果吧

首页

点击运行

容器页面

代码实现(只拿取一些代码)

首先server 里的 index.js 文件 (注释我已经写好了)

const koa = require('koa')
const routerRule = require('./router/router')
const views = require('koa-views')
const static = require('koa-static');
const path = require('path')
const app = new koa()

//加载html页面
const viewPath = './views'
app.use(views(path.join( __dirname,viewPath), {extension: 'ejs'}))

// 配置静态资源
const staticPath = './static'
app.use(static(
    path.join( __dirname, staticPath)
))

//配置路由
app.use(routerRule.routes())

//监听3322端口
app.listen(3322)

接着是 router/router.js 文件

const Router = require('koa-router')
const routerRule = new Router()
//加载dockerCmd 函数
const DockerCmd = require('../utils/dockerCmd')
const path = require('path')
const filePath = path.join(__dirname,"../../sh/")

//sh目录的全局变量
global.filePath = filePath
//DockerCmd函数的全局变量
global.DockerCmd = DockerCmd

//获取全部镜像
routerRule.get('/',require("../controller/index").all)

//删除某个镜像
routerRule.get('/delImage/:imageID',require("../controller/index").del)

//运行某个镜像
routerRule.get('/runImage/:image',require("../controller/index").run)

//获取全部容器
routerRule.get('/container',require("../controller/container").all)

//获取某个容器开启的镜像
routerRule.get('/container/:containerID',require("../controller/container").id)

//删除某个容器
routerRule.get('/delContainer/:containerID',require("../controller/container").del)

//停止某个容器
routerRule.get('/stopContainer/:containerID',require("../controller/container").stop)

//运行某个容器
routerRule.get('/startContainer/:containerID',require("../controller/container").run)

module.exports = routerRule

接着是 utils/dockerCmd.js 文件

const exec = require('child_process').exec
module.exports = class DockerCmd {
        static async execFile(cmdStr) {
                return new Promise((resolve, reject) => {
                        //执行传输过来的 shell命令
                        exec(cmdStr, (err, str, stderr) => {
                                if (err) {
                                        reject(err)
                                } else {
                                        resolve(str)
                                }
                        })
                })
        }
}

最后是controller 这个 文件里的 index.js文件

module.exports = class Index {
        static async all(ctx, next) {
                let str = `/bin/bash ${filePath}get_docker_images.sh`
                let res = await DockerCmd.execFile(str)
                let lists = []
                if (res) {
                        let arr = res.split(" ")
                        if (arr.length > 0) {
                                for (let i = 0; i < arr.length; i++) {
                                        if (arr[i] != "\n") {
                                                let list = arr[i].split("|")
                                        }
                                }
                        }
                }
                await ctx.render("index/index", { title: "docker镜像", lists: lists })
        }

module.exports = class Index {
        //获取全部镜像
        static async all(ctx, next) {
                let str = `/bin/bash ${filePath}get_docker_images.sh`
                let res = await DockerCmd.execFile(str)
                let lists = []
                if (res) {
                        let arr = res.split(" ")
                        if (arr.length > 0) {
                                for (let i = 0; i < arr.length; i++) {
                                        if (arr[i] != "\n") {
                                                let list = arr[i].split("|")
                                        }
                                }
                        }
                }
                await ctx.render("index/index", { title: "docker镜像", lists: lists })
        }

        //运行镜像
        static async run(ctx, next) {
                let str = `${ctx.params.image}`
                ctx.response.type = 'text/html'
                try {
                        let res = await DockerCmd.execFile(str)
                        ctx.response.body = res + " 运行成功!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                } catch (err) {
                        ctx.response.body = "运行失败!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                }
        }

        //删除镜像
        static async del(ctx,next)
        {
                let str = `docker rmi ${ctx.params.imageID}`
                ctx.response.type = 'text/html'
                try {
                        let res = await DockerCmd.execFile(str)
                        ctx.response.body = "删除成功!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                } catch (err) {
                        ctx.body = "删除失败!<a href='#' onclick='self.location=document.referrer;'>返回</a>"+err
                }
        }

}

container.js 文件

module.exports = class Container {
        //获取全部容器
        static async all(ctx, next) {
                let str = `/bin/bash ${filePath}get_docker_images_ps.sh`
                let res = await DockerCmd.execFile(str)
                let lists = []
                if (res) {
                        let arr = res.split(",")
                        if (arr.length > 0) {
                                for (let i = 0; i < arr.length; i++) {
                                        if (i != arr.length - 1) {
                                                let list = arr[i].split("|")
                                                let status_type = 0;//0为未运行或其他 1为运行中
                                                if (list[2].search("Up") != -1) {
                                                        status_type = 1
                                                }

                                        }
                                }
                        }
                }
                await ctx.render("container/index", { title: "docker容器", lists: lists })
        }
        //根据id获取容器
        static async id(ctx, next) {
                let str = `/bin/bash ${filePath}get_docker_images_ps.sh`
                let res = await DockerCmd.execFile(str)
                let lists = []
                let containerID = ctx.params.containerID
                if (res) {
                        let arr = res.split(",")
                        if (arr.length > 0) {
                                for (let i = 0; i < arr.length; i++) {
                                        if (i != arr.length - 1) {
                                                //是否是当前容器
                                                let add_list = false
                                                let list = arr[i].split("|")
                                                let containerName = containerID.split("&")
                                                if (containerName[0]) {
                                                        for (let j = 0; j < list[1].length; j++) {
                                                                if (containerName[0][j]) {
                                                                        if (containerName[0][j] != list[1][j]) {
                                                                                add_list = false
                                                                                break
                                                                        } else {
                                                                                add_list = true
                                                                        }
                                                                }
                                                        }
                                                if (containerName[1] && !add_list) {
                                                        if (containerName[1] == list[1]) {
                                                                add_list = true
                                                        } else {
                                                                add_list = false
                                                        }
                                                }

                                                if (containerName[2] && !add_list) {
                                                        if (containerName[2] == list[1]) {
                                                                add_list = true
                                                        } else {
                                                                add_list = false
                                                        }
                                                }


                                                if (add_list) {
                                                        let status_type = 0;//0为未运行或其他 1为运行中
                                                        if (list[2].search("Up") != -1) {
                                                                status_type = 1
                                                        }
                                                }
                                        }
                                }
                        }
                }
                await ctx.render("container/index", { title: "docker-" + containerID + "-容器", lists: lists })
        }

        //删除容器
        static async del(ctx, next) {
                let str = `docker rm ${ctx.params.containerID}`
                ctx.response.type = 'text/html'
                try {
                        let res = await DockerCmd.execFile(str)
                        ctx.response.body = "删除成功!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                } catch (err) {
                        ctx.body = "删除失败!<a href='#' onclick='self.location=document.referrer;'>返回</a> "+err
                }
        }

        //停止容器
        static async stop(ctx, next) {
                let str = `docker stop ${ctx.params.containerID}`
                ctx.response.type = 'text/html'
                try {
                        let res = await DockerCmd.execFile(str)
                        ctx.response.body = "停止成功!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                } catch (err) {
                        ctx.body = "停止失败!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                }
        }
        //运行容器
        static async run(ctx,next){
                let str = `docker start ${ctx.params.containerID}`
                ctx.response.type = 'text/html'
                try {
                        let res = await DockerCmd.execFile(str)
                        ctx.response.body = "运行成功!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                } catch (err) {
                        ctx.body = "运行失败!<a href='#' onclick='self.location=document.referrer;'>返回</a>"
                }
        }

}

最后就是 git地址 git@gitee.com:huxierong/dockerMsg.git

nodejs开发一个 网站百度关键字查询

我们首先 npm init

下载包

npm install koa

npm install request

npm install iconv-lite

npm install cheerio

然后目录如下

request.js文件是 进一步封装 request的get请求

var request = require('request');
var iconv = require('iconv-lite');
module.exports = class Request{
  static get(apiUrl)
  {
    return new Promise((resolve,reject)=>{
      request({
        url:apiUrl,
        method: "get",
        encoding: null,
        headers: {
          'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'
        }
      }, function(err, res, body) {
        if (err) {
          reject(null)
        } else {
          body = iconv.decode(body, 'utf-8');
          resolve(body)
        }
      })
    })
  }
}

我们先看baiduSeo.js 文件

这个文件 是用来获取传递过来的url 把keyword解析成数组返回

const request = require('../utils/requests.js');
const cheerio = require('cheerio');
module.exports = class BaiduSeo{
  
  //获取url
  async getUrl(url)
  {
    try{
      const data = await request.get(this.isHttp(url))
      if(data)
      {
        return this.parseData(data)
      }else{
        return null
      }
    }catch(error)
    {
      return null
    }
  }

  //判断是否有http
  isHttp(url)
  {
    if(url.search("http")!=-1)
    {
      return url
    }else{
      return "http://"+url
    }
  }

  //解析数据
  parseData(data)
  {
    if(data!=null)
    {
      const get = cheerio.load(data)
      const keyword = get("meta[name=keywords]").attr('content')
      const keywords = keyword.split(',')
      let arr = []
      if(keywords.length>0)
      {
        for(let i=0;i<keywords.length;i++)
        {
          arr.push({name:keywords[i]})
        }
        return arr
      }else{
        return null
      }
    }else{
      return null
    }
  }
  
}

接着我们来看看 seoRank.js 文件 它是返回 某个网站的某个关键字 是否在百度前10页 如果是就返回当前页,否则返回0

const request = require('../utils/requests.js');
const cheerio = require('cheerio');
module.exports = class SeoRank{
  
  //获取数据
  async getData(data,searchName)
  {
    let rank = {name:data,rank:0}
    searchName = await this.delMaterial(searchName)
    for(let i=0;i<10;i++)
    {
      let page = i*10
      let urlStr = `https://www.baidu.com/s?ie=utf-8&wd=${data}&pn=${page}`
      let url = encodeURI(urlStr)
      let response = await request.get(url)
      if(response.search(searchName)!=-1)
      {
        rank = {name:data,rank:i+1}
        return rank
      }
    }
    return rank
  }

  //去掉https:// http:// 斜杠 保留
  async delMaterial(url)
  {
    return url.replace(/\//g,'').replace("https:","").replace("http:","")
  }

}

接着 我们创建一个中间件 searchKeyword.js 这个文件是根据get请求来 判断是获取 关键字 还是 当前关键字的排名

const BaiduSeo = require('../middleware/baiduSeo');
const SeoRank = require('../middleware/seoRank');
module.exports = async function searchKeyword(ctx,next)
{
  let query = ctx.request.query
  if(query['type'])
  {
    if(query['type'] && query['url'])
    {
      if(query['type']=="getKeyword")
      {
        let baiduSeo = new BaiduSeo()
        const keyword = await baiduSeo.getUrl(query['url'])
        if(keyword)
        {
          ctx.body = keyword
        }else{
          ctx.body = "null"
        }
      }else if(query['type']=="searchKeyword" && query['keyword'])
      {
        let rank = []
        let seoRank = await (new SeoRank()).getData(query['keyword'],query['url'])
        rank.push(seoRank)
        ctx.body = rank
      }else{
        ctx.body = "null"
      }
    }else{
      ctx.body = "null"
    }
  }
  else{
    ctx.body = "null"
  }
  await next()
}

好了到了我们的index.js 文件了 使用koa框架

const Koa = require("Koa")
const app = new Koa()
const SearchKeyword = require('./use/searchKeyword')
app.use(SearchKeyword)
app.listen(8776)
console.log("run")

现在我们可以运行下看看 首先是获取全部关键字

接着根据某个关键字来获取 排名

也就是说这个关键字 在百度第4页

当然这里面还有点bug

typescript简单实现ajax请求

我们首先定义一个接口

interface UtilConfig{
  url:string;
  method:string;
  data:string;
  dataType:string;
  success:(str:JSON | string)=>void;
  error?:(str:string)=>void;
}

接着我们编写一个函数我就把它取名为ajax

function ajax(config:UtilConfig):void{
  let xhr = new XMLHttpRequest()
  xhr.open(config.method,config.url,true)
  xhr.send(config.data)
  xhr.onreadystatechange = function()
  {
    if(xhr.readyState==4){
      if(xhr.status==200)
      {
        if(config.dataType.toLowerCase()=="json")
        {
          config.success(JSON.parse(xhr.responseText))
        }else{
          config.success(xhr.responseText)
        }
      }else{
        if(config.error)
        {
          config.error(xhr.responseText)
        }
      }
    }
  }
}

这个函数的参数用来指定接口 里面就是实现XmlHttpRequest类来发送请求

接着我们允许一下这个函数

ajax({
  url:"http://localhost:5666/api/v1/getId/1",
  method:"get",
  data:'id=1',
  dataType:"json",
  success:(res:string | JSON)=>
  {
    console.log(res)
  },
  error:(res:string)=>{
    console.log(res)
  }
})

查看结果

ok成功

手机版b站 使用puppeteer爬取分类,和分类下最新的视频信息

目录结构

data 爬取操作
config 一些配置项
database 爬取数据库
handle 处理爬取到的数据写进数据库中

index.js 文件

里的runPa 方法是处理 数组里要处理的爬取文件(data)

runPa方法里通过 child.on(“message” ) 来做进程间的通讯

data 目录下的 js文件 通过 process.send({result}) 方法与index.js通讯

handle 里的js文件

通过 传进来的 res 来入库处理。

git地址 https://gitee.com/huxierong/bilbil_pachongg

简单构建工具parcel 轻松构建vue

首先

npm init

然后下载 vue parcel

npm install vue

npm install parcel-bundler

目录结构

App.vue

<template>
    <div>
        app
        <img src="./d.jpg" alt="">
    </div>
</template>

<script>
export default {
  data() {
    return {};
  }
};
</script>

<style lang="stylus" scoped>
div
    font-size 30px
</style>

main.js

import Vue from 'vue'
import App from './App.vue'

new Vue({
  el: '#app',
  render: h => h(App)
})

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <meta http-equiv="X-UA-Compatible" content="ie=edge">
  <title>Document</title>
</head>
<body>
  <div id="app"></div>
  <script src="./src/main.js"></script>
</body>
</html>

下载css预处理器 stylus

npm install stylus stylus-loader -D

运行 parcel index.html

parcel文档 https://parceljs.org/getting_started.html