日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > vue >内容正文

vue

使用 vue + thinkjs 开发博客程序记录

發布時間:2025/3/20 vue 49 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用 vue + thinkjs 开发博客程序记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一入冬懶癌發作,給自己找點事干。之前博客程序寫過幾次,php 的寫過兩次,nodejs 用 ThinkJS 寫過,隨著 ThinkJS 版本從1.x 升級到 2.x 之前的博客程序也做過升級。但是因為前面考慮搜索引擎抓取還是用傳統的方式開發,沒有做前后端分離。這次準備用 vue2.x 和 ThinkJS 3.X 重新寫一次。這里主要記錄一下開發過程中遇到的問題和解決方法。

地址 https://github.com/lscho/Thin...

尚未寫完,持續更新中,后續更新發布在個人博客中:https://lscho.com/tech/vue-th...

設計方案

1.前后端分離
2.后端只提供接口
3.RESTful API
4.使用 jwt 身份認證

依賴

服務端

"dependencies": {"think-logger3": "^1.0.0","think-model": "^1.0.0","think-model-mysql": "^1.0.0","think-session": "^1.0.0","think-session-jwt": "^1.0.8","thinkjs": "^3.0.0"}

前端

"dependencies": {"axios": "^0.17.0","iview": "^2.5.1","mavon-editor": "^2.4.13","vue": "^2.5.2","vue-axios": "^2.0.2","vue-router": "^3.0.1","vuex": "^3.0.0","vuex-router-sync": "^5.0.0"}

結構

|-client 前端
|-server 后端

問題

jwt 身份認證

jwt 的原理很清楚,之前自己也實現過類似的功能,搜索了一下,找到了 node-jsonwebtoken 這個包,使用起來很簡單,主要就是加密和解密兩個功能。一番折騰之后成功運行,但是去 ThinkJS 倉庫看了一下,竟然有發現了 think-session-jwt 這個插件,也是基于 node-jsonwebtoken 的。這個就更好用了,配置完之后直接用 ThinkJS 的 ctx.session 方法就可以生成和驗證。配置的時候需要注意一下 tokenType 這個參數,他決定了如何獲取 token ,我這里用的是 header ,也就是說后面會從每個請求的 header 中找 token,key 值為配置的 tokenName。

然后要處理前端部分,為每個請求附加上 token。這里我用的是 axios ,在請求攔截器中很方便的就可以加上。

let loadinginstace; axios.interceptors.request.use(config => {if (localStorage.getItem('token')) { config.headers.Authorization = localStorage.getItem('token')} return config; },error => {return error; })

然后登錄之后的每個請求中就可以看到

后端權限認證

因為 API 接口遵循 RESTful 風格,所以對除了 GET 類型的請求,都要驗證 token 是否有效,ThinkJS 的控制器提供了前置操作 __before。在這里可以做一下邏輯判斷,通過的才會繼續執行。

async __before(action) {try {this.userInfo=await this.ctx.session('userInfo');} catch(err) {this.userInfo={};}if(this.resource!='token'&&this.ctx.method!='GET'&&think.isEmpty(this.userInfo)){this.ctx.status=401;return this.ctx.fail(-1,"請登錄后操作");}}

這里遇到一個問題,就是當 token 為錯誤時,node-jsonwebtoken 會拋出一個異常,所以這里用了 try catch 捕獲,可能有更好的解決辦法,暫時放后面處理。

前端身份失效檢測

為了安全起見,我們的 token 一般設置的都有效期,所以有兩種情況需要我們進行處理.

  • token 不存在,這種很好處理,直接在路由的前置操作中判斷是否存在,存在則放行,不存在則轉向登錄界面
  • beforeEnter:(to, from, next)=>{if(!localStorage.getItem('token')){next({ path: '/login' });}else{next();}}

    2.token 超過有效期或者被篡改。這種需要后端檢測之后才能知道該 token 是否有效。這里服務端檢測失效之后會返回 401 狀態碼以便前端識別。

    if(this.resource!='token'&&this.ctx.method!='GET'&&think.isEmpty(this.userInfo)){this.ctx.status=401;return this.ctx.fail(-1,"請登錄后操作");}

    我們在axios的請求響應攔截器中進行判斷即可,因為 4XX 的狀態碼會拋出異常,所以代碼如下

    axios.interceptors.response.use(data => {//這里可以對成功的請求進行各種處理return data; },error=>{if (error.response) {switch (error.response.status) {case 401:store.commit("clearToken");router.replace("/login");break;}}return Promise.reject(error.response.data) })

    markdown 編輯器及文件上傳

    markdown 編輯器用了 mavonEditor 配置很方便,不多說,主要說一下文件上傳遇到的一個問題。
    前端代碼

    <mavon-editor ref=md @imgAdd="imgAdd" class="editor" v-model="formItem.content"></mavon-editor> imgAdd(pos, $file){var formdata = new FormData();formdata.append('image', $file); image.upload(formdata).then(res=>{if(res.errno==0&&res.data.url){this.$refs.md.$img2Url(pos, res.data.url);}}); }

    后端處理

    const file = this.file('image');const extname=path.extname(file.name);//path.extname獲取文件后綴名,可做控制const filename = path.basename(file.path);const basename=think.md5(filename)+extname;const savepath = '/upload/'+basename;const filepath = path.join(think.ROOT_PATH, "www"+savepath);think.mkdir(path.dirname(filepath));try{//跨盤符移動會拋出異常await rename(file.path, filepath);}catch(e){const readStream = fs.createReadStream(file.path);const writeStream = fs.createWriteStream(filepath);readStream.pipe(writeStream);}

    這里也用了一個 try catch 來捕獲異常,主要是因為 ThinkJS 會將上傳的文件先放到臨時目錄中,而在 windows 下臨時目錄可能和項目目錄不在同一盤符下,進行移動的話就會拋出一個異常:Error: EXDEV, cross-device link not permitted,沒有權限移動,這時候就只能先讀文件,再寫文件

    2017-12-27 更新 在群里@阿特 大佬提到,可以對 payload
    這個中間件設置指定臨時目錄為項目下的某個目錄,這樣就不存在跨盤

    ``` { handle: 'payload', options: { uploadDir: path.join(think.ROOT_PATH, 'runtime/data') } } ```

    這樣就可以直接使用 rename 來操作了,關于跨盤 rename 的問題,在 https://github.com/nodejs/nod... 找到了原因,大意是操作系統限制 rename 僅僅是重命名路徑引用地址,并沒有將數據移動過去,重命名不能跨文件系統操作,所以如果跨文件系統操作需要先復制、然后刪除舊數據

    部署

    因為前端路由使用 history 模式,所以要將請求轉發至 index.html 入口頁面處理,跟有些 mvc 框架單入口是一個概念。

    # 請求轉發至入口location / {try_files $uri $uri/ /index.html;}

    然后還要處理一下后端請求部分,如果不是同一域名,就要解決跨域問題。這里前后端使用同一個域名,針對 api 請求做一下反向代理即可。

    set $node_port 8360;location ~ ^/api/ {proxy_http_version 1.1;proxy_set_header X-Real-IP $remote_addr;proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;proxy_set_header Host $http_host;proxy_set_header X-NginX-Proxy true;proxy_set_header Upgrade $http_upgrade;proxy_set_header Connection "upgrade";proxy_pass http://127.0.0.1:$node_port$request_uri;proxy_redirect off;}

    后端使用 pm2 守護進程即可。

    原文地址:https://segmentfault.com/a/1190000012610084

    轉載于:https://www.cnblogs.com/lalalagq/p/9960315.html

    總結

    以上是生活随笔為你收集整理的使用 vue + thinkjs 开发博客程序记录的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。