使用了Node和Vue寫了個部落格園的移動端WebApp,想拿出來與大家分享下,也談談我遇到的坑。由於時間問題,目前還剩“快閃記憶體”,“博問”這兩塊還沒做完。先分享下截圖吧。
我呢,就從技術,部署,以及遇到的坑來講吧,當然啦,首先要感謝部落格園官方提供介面,以及客服人員對於我的“郵箱轟炸”,還回復我的問題。致以大大的感謝。
說說我使用的技術吧
- 開發工具:vs code
- 前端:vue,vue-cli3.0 vant(ui框架),webpack,less
- 後端:部落格園官方api
- 部署:nginx,雲伺服器
技術就是這麼簡單,開發工具就不講了,前端採用腳手架構建而成,就不用自己累死累活去配置,這個時代真好。然後再使用vant的UI框架構建樣式介面,webpack打包嘛,less專注樣式咯,後端就完全是部落格園的api了,拿來即用,不過介面要申請下許可權。前後端的請求,我採用的是“axios”,使用它的攔截器做了不少事。然後部署的話,我呢,就生成靜態了,然後用nginx部署在阿里雲伺服器上了。
技術想講的就這些,vue是基礎,若是vue不懂,可以去我之前的文章看看,不過呢,我更建議去官方文件上去學習,其他的也是,我只是比較喜歡寫寫文章。由這些技術,我就構建了一個webapp。
我遇到的大坑
-
token問題
部落格園的介面採用的是OAuth2的形式,所以授權玩會附帶一個token給我們,那遇到的token是啥問題呢,我們都知道token是
時效性的,所以一般來說拿到就要儲存下來,儲存沒問題,可以儲存到cookie來,但是你再次訪問,怎麼知道token過期呢,還有進行重新獲取呢。為啥說這個是大坑呢,因為以前都是jQuery的ajax,沒有用過axios,不知道攔截器這種東西,我們使用攔截器,進行攔截"401"的轉態碼,因為它代表著未授權,攔截到後我們重新請求token,儲存,並重新請求剛才的http。附上程式碼。
- instance.interceptors.request.use(
- config => {
- let token = window.$cookies.get(_apiTokenKey) || "";
- config.headers.Authorization = `Bearer ${token}`;
- return config;
- },
- error => {
- return Promise.reject(error);
- }
- );
- instance.interceptors.response.use(
- response => {
- return response.data;
- },
- error => {
- let response = error.response;
- let config = error.config;
- if (response.status === 401) {
- getApiToken().then(res => {
- config.baseURL = '';
- instance(config)
- }).catch(res=>{
- window.$vm.$toast({
- message: error.message
- });
- });
- }else{
- window.$vm.$toast({
- message: error.message
- });
- }
- return Promise.reject(error);
- }
- );
-
跨域問題
對於部落格園的介面地址,我們屬於不同域的情況,可能你用POSTMAN來進行介面除錯的情況,可以正常獲取到資料,但實際在專案內我們卻會遇到跨域問題。這也是很多作為前後端分離專案,優先考慮的問題。在這分為開發環境以及線上環境,線上環境會在下面講到,我們先講下開發環境底下的跨域問題。
因為開發環境是在Node.js底下嘛,所以我採用的是webpack的跨域外掛"http-proxy-middleware"來進行跨域的,因為vue-cli3.0,它整合在"vue.config.js"底下,配置如下:
- devServer: {
- host: "192.168.123.22",
- port: 8080,
- proxy: {
- "/credentials": {
- target: "https://api.cnblogs.com",
- changeOrigin: true,
- secure: true,
- pathRewrite: {
- "^/credentials": "" //這裡理解成用‘/api’代替target裡面的地址,後面元件中我們掉介面時直接用api代替 比如我要呼叫'http://40.00.100.100:3002/user/add',直接寫‘/api/user/add’即可
- }
- },
- "/api": {
- target: "https://api.cnblogs.com/api",
- changeOrigin: true,
- secure: true,
- pathRewrite: {
- "^/api": "" //這裡理解成用‘/api’代替target裡面的地址,後面元件中我們掉介面時直接用api代替 比如我要呼叫'http://40.00.100.100:3002/user/add',直接寫‘/api/user/add’即可
- }
- },
- "/oauth": {
- target: "https://oauth.cnblogs.com",
- changeOrigin: true,
- secure: false,
- pathRewrite:{
- "^/oauth":""
- }
- }
- }
- }
具體作用嘛,大家看官方文件咯,https://webpack.docschina.org/configuration/dev-server/#devserver-proxy
-
登入問題
接下來就是登入問題,剛才我們講過了部落格園是採用OAuth2的授權,這邊部落格園還分為兩種。不涉及使用者操作的授權採用的是"授權碼模式",而有關使用者操作的授權採用的是"密碼模式",兩者區分大家可以看這篇文章。那意味著我們在WebApp管理兩個token。管理兩個token不是大坑,無非就是兩個token嘛,大坑指的是我們獲取使用者操作的token是需要先使用者進行登入操作,然後回撥一個授權碼的。我們來分析下。
- 介面問題
從上圖的介面描述我們可以得知,我們要先或許授權碼code,但是code是有回撥地址redirect_uri引數傳過來的,這邊是預設部落格園的地址的,安卓或者ios的開發,可以根據webView的監聽來獲取,但是Web這邊就存在跨域的問題了,我嘗試了很多方式,有iframe等等,但是最根本的問題,頁面在人家手上,你碰不著,這也就是大坑了,然後我就聯絡管理員,官方把回撥地址改成我這邊設定好的域名。真的很感謝管理員及其部落格園的開發。
但在這之前,我就想著說,如果改不成,那就換成引導式的方法來引導使用者進行自己講授權碼複製回來,然後貼上到我們設定到的授權頁面,也就有下圖的介面,所以即使回撥地址不是我們們這邊的,也可以進行登入授權。可以點選"獲取授權碼"來跳轉頁面,獲取授權碼,然後回到這個頁面登入。
- vue路由問題
一般來說,單頁面開發使用的路由都是hash形式的路由,但是回撥地址返回的引數是附帶在#後面的,我們hash路由自帶#,兩者起衝突了,沒辦法,我們改成history形式的路由。
- let routers = new Router({
- mode: 'history',
- routes: config
- });
- 介面問題
-
圖片防盜鏈
最後剩下一個坑,也就是圖片防盜鏈吧,正常部落格園的博問內容有些地址是image.cnblogs的地址,所以我們附在了我們自己的域名底下就會出現防盜鏈的結果,那如何處理防盜鏈呢,這邊有2種做法,第一種是在head加上<meta name="referrer" content="no-referrer">
來標識,第一種是使用vue的過濾器,然後用第三方代理去請求圖片。這樣子就可以了,不過代理的地址是cdn,所以可能找不到圖片。- const imgConvert = url => {
- //沒有在nginx做反向代理,直接用別人的反向代理訪問,
- //該地址是cdn快取圖片存在,可能找不到圖片
- if(url==undefined||url==null){
- url="";
- }
- url = url
- .replace("http://", "")
- .replace("https://", "")
- .replace("https:", "");
- return `https://images.weserv.nl/?url=${url}`;
- };
- <img class="blog-item_faceImg" :src="item.Avatar | imgConvert" @error="errorFace" @click="gotoZone">
-
總結下吧
整體來說,整個專案挺好做的,思路也很清晰,唯一就是跨域問題比較有點,但最終也是解決了。還不錯吧。
怎麼去部署呢
在前面說到,我部署是使用雲伺服器+nginx,至於怎麼安裝nginx不懂可以私信我,或者百度嘛,我這邊分享下我nginx的配置節點就可以了。當然如果還想要部署在外網環境,可以的話雲伺服器來一臺,或者做個內網穿透,frp,ngrok之類的就可以,廢話不多說,附上節點程式碼:
- server{
- listen 80;
- server_name cnblog.xuhuale.cn;
- root /ftpfiles/cnblog/dist;
- index index.html index.htm index.php;
- location / {
- try_files $uri $uri/ @router;
- index index.html;
- # error_page 405 =200 http://$host$request_uri;
- }
- location @router{
- rewrite ^.*$ /index.html last;
- }
- location /api {
- error_log logs/rewrite.log notice;
- # rewrite ^/api/(.*) /$1 break;
- proxy_pass https://api.cnblogs.com;
- }
- location /credentials {
- error_log logs/rewrite.log notice;
- rewrite ^/credentials/(.*) /$1 break;
- proxy_pass https://api.cnblogs.com;
- }
- location /oauth {
- error_log logs/rewrite.log notice;
- rewrite ^/oauth/(.*) /$1 break;
- proxy_pass https://oauth.cnblogs.com;
- }
- }
我們可以看到配置節點有"proxy_pass"這個就是nginx做的反向代理了,可以解決掉跨域問題。
總結下吧
我平時喜歡逛逛部落格園的文章,但是移動端直接訪問網頁沒有適配,手機端還是需要下載軟體,所以我就想著做個webapp版的,想要嵌入Android,ios也可以,掛在公眾號也可以,直接訪問也可以,愛咋咋地。然後發現了api,又最近在練手vue,所以就做了一個出來,但是內容還沒完善,後面可以會完善起來,大家要是有在移動端裝置看部落格的習慣,可以收藏網址一波,或者大家進去捧捧場咯。最後附上原始碼地址,網站地址,還有網站二維碼,以便手機掃嘛。
1.原始碼地址:https://github.com/xhl592576605/cnblog_vue
2.網站地址:http://cnblog.xuhuale.cn(建議使用移動端的模式訪問,觀感更加)
3.二維碼: