我的網站構建記錄

想過要作我的網站,因爲感受過程特別繁瑣及技術緣由一直拖着,6.18買了個服務器,因此just do it否則有點浪費。html

準備

作了個簡易版的網站,寫這篇文章主要是爲了梳理一下本身的思路,主要涉及:mysql,node,axios請求,vue打包文件上傳到服務器,nginx,pm2管理node服務 這幾個部分,我也會分別來描述這幾方面的構建過程。前端

mysql數據庫

在此以前沒有接觸過數據庫,印象中就是增刪改查。再決定要寫node後臺我決定系統的學習下mysql的語法,這裏推薦本身這幾天看的b站的mysql視頻相信你的sql語句也會寫的槓槓的。vue

其實對於前端來講用的最多的就是查,再準備寫項目前創建一個數據庫,根據頁面的增長,增長數據庫中的表。具體的語法能夠自行查閱資料,或者看我推薦的視頻。node

node

有了數據,咱們須要使用js來操做數據庫裏的數據。這裏咱們會用到npm mysql包,經過mysql庫來建立與mysql鏈接池,而後可使用上面學的sql語句來操做數據庫如:mysql

connection.query('SELECT * FROM `books` WHERE `author` = "David"', function (error, results, fields) {});
複製代碼

雖然會寫一些sql語句了,可是我用的不是這款js庫,我仍是比較喜歡sequelize寫起來比較簡潔優雅。
有了sequelize庫,咱們須要建立Model(至關於數據庫中表)經過它來操做一個表中數據的增刪改查。咱們會寫一些代碼以下:webpack

// 鏈接數據庫
const sequelize = new Sequelize('minprogram', 'root', 'password', {
  host: 'localhost',
  dialect: 'mysql'
})
// 指定一個表
const User = sequelize.define(
  'user',
  {
    id: {
      type: Sequelize.STRING(10),
      primaryKey: true,
      autoIncrement: true
    },
    avatar: Sequelize.STRING(100),
    createdAt: Sequelize.BIGINT,
    updatedAt: Sequelize.BIGINT
  },
  { timestamps: false }
)
複製代碼

有了model模型後咱們能夠開始操做數據庫了,能夠把操做數據的方法單獨存放在對應的業務邏輯下如:ios

// user.js
const User = require('./model')
async function findAll() {
  return User.findAll()
}
async function createUserId(options) {
  return User.create(options)
}
async function getId(id) {
  return User.findAll({
    where: { id: id }
  })
}
module.exports = {
  findAll,
  createOpenid,
  getOpenid,
  updateTime
}
複製代碼

------------------分割線-------------------nginx

有了操做數據庫的能力,能夠開始寫一些後臺邏輯和接口了。好比要作一個登錄的驗證,判斷(是否有該用戶,用戶密碼是否正確)的邏輯。
來梳理下邏輯的實現思路:git

  1. 當點擊登錄按鈕時調用登錄接口,服務端查詢根據用戶名查詢數據庫中是否存在該用戶名(不存在多個相同的用戶名,註冊時就要將該狀況規避,提醒用戶已經註冊)
  2. 查詢數據庫發現找不到數據,說明該用戶名還未註冊
  3. 查詢數據庫發現密碼和用戶輸入的密碼不符,提示密碼輸入成功
  4. 還能夠設置登錄過時之類的,目前還沒作,到此就算登錄成功了吧
// 項目使用koa框架
// 統必定義類型,便於後期修改維護
const jsonMine = 'application/json'

router.get('/vue/login', async ctx => {
    const { username, password } = ctx.request.query
    const allList = await findUserByName(username)
    if (allList.length === 0) {
      handle(ctx, '', 1, '該用戶未註冊')
    } else {
      if (allList[0].password !== password) {
        handle(ctx, '', 1, '密碼錯誤')
      } else {
        handle(ctx, '', 0, '登錄成功')
      }
    }
  })
// 統一處理返回數據
function handle(ctx, data, code = 0, message = 'success') {
  ctx.type = jsonMine
  ctx.body = {
    code,
    data,
    message
  }
}
複製代碼

axios請求 跨域問題

對axios進行了一些封裝,而後去請求後臺服務我設置對端口號是8082。github

import axios from 'axios'
export default ({ api, params }) => {
  const baseURL = 'http://' + window.location.hostname + ':8082'
  return axios({
    url: api,
    method: 'get',
    baseURL,
    // headers: { 'client-test': 'cors' },
    params,
    'Content-Type': 'application/x-www-form-urlencoded'
  }).then(res => {
    const { status } = res
    if (
      (status >= 200 && status < 300) ||
      status === 304 ||
      status === 302
    ) {
      return new Promise((resolve, reject) => {
        resolve(res.data)
      })
    } else {
      return Promise.reject(
        new Error(
          `${'*'.repeat(10)}  狀態嗎:${status}  ${'*'.repeat(
            10
          )}\n ${'*'.repeat(10)}  api:  ${'*'.repeat(10)}\n ${'*'.repeat(
            10
          )}  `
        )
      )
    }
  })
}
複製代碼

出現跨域對問題。控制檯打出錯誤提示須要咱們後臺設置容許訪問的域。也就是設置 Access-Control-Allow-Origin字段。
能夠寫一個中間件cors.js,這樣統一處理全部路由:

  • 核心代碼就是 let origin = options.origin || ctx.get('Origin') || '*' ctx.set('Access-Control-Allow-Origin', origin)
// cors.js
module.exports = function crossOrigin(options = {}) {
  const defaultOptions = {
    allowMethods: ['GET', 'PUT', 'POST', 'PATCH', 'DELETE', 'HEAD', 'OPTIONS']
  }

  options = Object.assign({}, defaultOptions, options) 
  return async function cors(ctx, next) {
    // 設置容許訪問後臺對域,能夠自行設置,或者取請求頭中的origin,再不行就是全部的域均可以訪問
    let origin = options.origin || ctx.get('Origin') || '*'
    ctx.set('Access-Control-Allow-Origin', origin)

    if (ctx.method === 'OPTIONS') {
      if (options.allowMethods) {
        ctx.set('Access-Control-Allow-Methods', options.allowMethods.join(','))
      }
      // Access-Control-Allow-Headers
      if (options.allowHeaders) {
        ctx.set('Access-Control-Allow-Headers', options.allowHeaders.join(','))
      } else {
        ctx.set(
          'Access-Control-Allow-Headers',
          ctx.get('Access-Control-Request-Headers')
        )
      }

      ctx.status = 204 // No Content
    } else {
        ctx.set('Access-Control-Allow-Credentials', 'true')
      }
      await next()
    }
  }
}

複製代碼

vue打包文件上傳到服務器

完成了客戶端訪問服務端並拿到數據更新UI和狀態。將完成的代碼經過webpack打包。生成以下文件,接下來就是將dist文件夾發到服務器上指定的目錄下。

  • 發送步驟以下
  1. tar -cvf dist.tar dist 將 dist 文件夾壓縮在根目錄下生成 dist.tar 文件
  2. scp dist.tar root@118.31.127.59:/repo/dist 將 dist.tar 文件上傳到服務對應到路徑下
  3. tar -xvf dist 解壓 dist.tar 文件 還原 dist 文件夾

nginx 代理

經過nginx代理指向服務器本地的index.html,當訪問域名時至關於打開的是服務器指定目錄下的index.html文件。
在服務器安裝nginx的狀況下 vi /etc/nginx/nginx.conf 打開配置文件查看下。可自行查看,發現一大堆也看不懂的東西,就看到一句include /etc/nginx/conf.d/*.conf;

意思是會引入conf.d文件下的因此.conf結尾的配置文件。因此爲了看着舒服,在 /etc/nginx/conf.d目錄下新建一個html.conf文件來單獨寫本身的nginx配置。

server {
   listen 8980 ;
   server_name 118.31.127.59;
   root /repo ;
   location /dist {
      index index.html;
   }
 }
複製代碼

這個配置經過root 指定根目錄,經過location 指定uri 。當頁面訪問118.31.127.59:8980/repo/dist 是會打開該目錄下當index.html文件。

  • 疑問爲何本地打開dist文件夾下的html文件運行報錯,服務器端經過nginx代理就能夠正確打開? 關鍵仍是路徑問題,若是想在本地的dist文件夾下正確打開,須要路徑從 file://開始,而服務器中經過nginx指定根目錄爲 /repo 這樣能夠拿到正確的文件路徑。

service

  • 使用pm2管理node服務端的代碼
    1. pm2 ecosystem 在(local 本地)項目的根目錄下執行,生成配置文件,指定服務地址和github地址
    2. 初始化服務器,這樣服務器上就 copy 本地的項目文件 pm2 deploy ecosystem.config.js production setup
    3. 部署 pm2 deploy ecosystem.config.js production
    4. 在服務器中 pm2 start app.js 啓動node服務

第一次構建我的網站

如今面臨的問題是打開頁面加載時間太長。還有不少值得學習優化的地方,歡迎👏大佬在留言區給我提建議和交流。

相關文章
相關標籤/搜索