Node — 第七天 (大事件項目接口實現一)

關于JS錯誤處理

node中和mysql中的錯誤處理

node和MySQL提供的方法,已經對錯誤信息進行了封裝,只需要使用 err.message 即可獲取到錯誤信息。

比如:

const fs = require('fs');
// 讀取一個不存在的文件
fs.readFile('abcd.txt', (err, data) => {if (err) return console.log(err.message); // ENOENT: no such file or directory, open 'abcd.txt'console.log(data);
});

比如:試著修改下面的代碼,讓代碼產生錯誤,然后可以通過 err.message獲取到錯誤信息

function db (sql, params, cb) {const mysql = require('mysql');const conn = mysql.createConnection({host: 'localhost',user: 'root',password: '12345678',database: 'user'});conn.connect();conn.query(sql, params, cb);conn.end();
}db('insert into books set ?', {bookname: 'aaa', author: 'bbb', publisher: 'ccc'
}, (err, result) => {if (err) return console.log(err.message);console.log(result);
});

JS中的錯誤處理


// 使用try...catch...finally...這種語句可以獲取錯誤信息
// try : 嘗試
// catch : 捕獲、抓
// finally : 最終// 語法
/*** try { ... } catch (e) { ... }* * try { ... } finally { ... }* * try { ... } catch (e) { ... } finally { ... }*/// function abc () {
//     console.log(123);
// }// try {
//     abc();
// } catch (e) {
//     // e 是一個錯誤對象
//     console.log(e.message); // abc is not defined
// }try {abc();
} catch (e) {console.log(e.message);
} finally {console.log('哈哈哈');
}

try里面有大段的代碼,那么也是執行這一大段代碼,如果哪一行出了錯誤,會終止try里面代碼的執行,并且會把錯誤交給catch來處理。

new Error()

Error是JS內置對象,用于創建錯誤對象。

語法:

new Error('錯誤信息', '產生錯誤的文件', '錯誤的行號');
// 使用的時候,一般后面兩個參數不用填,默認使用當前的文件,錯誤的行號使用產生錯誤哪一行的行號。

throw關鍵字

throw 關鍵字用于拋出錯誤。

throw 后面可以跟數字、字符串、對象等等。

通過throw拋出的錯誤,可以被catch捕獲到。

  • throw 字符串
    • catch 中,使用 e 獲取錯誤信息
  • throw new Error(‘哈哈哈’);
    • catch 中,使用 e.message 獲取錯誤信息
try {// throw 'hahah';throw new Error('我自己定的錯誤');
} catch (e) {// console.log(e);console.log(e.message);
}
//===============================================================================

搭建大事件接口項目

已知使用到的第三方模塊有:

//設置跨域
const cors = require('cors');
//路徑查找
const path = require('path');
//設置分類路由,及請求體
const express = require('express');
// 使用express-jwt模塊,控制 以 /my 開頭的接口,需要正確的token才能訪問
const expressJWT = require('express-jwt');
//設置登錄權限,加載jsonwebtoken模塊(用于生成token加密串)
const jwt = require('jsonwebtoken');
//設置md5的密碼加密設置
const utility = require('utility');
//鏈接數據庫
const mysql = require('mysql');
//用于獲取formdata類型的請求體,同時完成文件上傳
const multer = require('multer');

創建項目目錄

創建 big-event-server 文件夾

下載安裝第三方模塊

npm init -y
npm i express mysql cors multer express-jwt jsonwebtoken
  • express 用于搭建服務器
  • mysql 用于操作數據庫
  • cors 用于解決跨域
  • multer 用于完成文件上傳
  • express-jwt 用于解密token字符串
  • jsonwebtoken 用于加密token字符串

創建routers文件夾,準備路由文件

項目根目錄創建了routers文件夾,里面創建如下四個路由文件

  • user.js 用于完成 個人中心 所需的接口
  • login.js 用于完成 登錄、注冊接口
  • article.js 用于完成 文章模塊 所需的接口
  • category.js 用于完成 文章類別 所需的接口

四個路由文件中,里面添加如下基礎代碼

const express = require('express');
const router = express.Router();// router.get('xxx', async (req, res) => {// });module.exports = router;

創建app.js,開啟服務

const path = require('path');const express = require('express');
const app = express();
app.listen(3007, () => console.log('大事件服務器啟動了'));// 加載路由模塊,并注冊成中間件
app.use('/api', require(path.join(__dirname, 'routers', 'login')));
app.use('/my/article', require(path.join(__dirname, 'routers', 'category')));
app.use('/my/article', require(path.join(__dirname, 'routers', 'article')));
app.use('/my', require(path.join(__dirname, 'routers', 'user')));

路由模塊的前綴,我們參考 劉龍賓 老師的接口文檔,和他的接口一樣即可。
大事件接口提示入口:

封裝db

/*** 導出函數,作用是完成mysql操作(增刪改查)* @param sql SQL語句* @param params 為SQL語句中的占位符傳遞的值,默認是null* @returns Promise對象*/
module.exports = (sql, params = null) => {const mysql = require('mysql');const conn = mysql.createConnection({host: 'localhost',user: 'root',password: '12345678',database: 'big-event', // 數據庫一會創建 });return new Promise((resolve, reject) => {conn.connect();conn.query(sql, params, (err, result) => {err ? reject(err) : resolve(result);});conn.end();});
}

使用Git管理項目

# 初始化
git init

模塊化阻止文件 .gitignore

接下來,需要執行add和commit命令把基礎的代碼提交到本地倉庫。但是 第三方模塊 沒有必要提交到倉庫,所以可以設置忽略文件 (.gitignore),內容如下:

# # 表示注釋
# 下面設置項目忽略的文件# 忽略abc.js文件
abc.js# 忽略xyz文件夾里面所有的文件
xyz# 忽略 node 第三方模塊
package-lock.json
node_modules

設置忽略之后,可以執行 git add .git commit -m '提交了初始的代碼'

如果需要上傳至 ‘碼云’ 或 ‘github’ 教程須知 https://blog.csdn.net/weixin_44694682/category_9920006.html

設置應用級別的中間件

  • 解決跨域

  • post請求體(urlencoded類型,也就是查詢字符串類型)

  • 開放靜態資源(開放上傳后的圖片)

/*                   app.js 加入如下代碼: */
const cors = require('cors');
// ----------  加載路由模塊之前,設置應用級別的中間件
// 解決跨域
app.use(cors());
// 接收 urlencoded 類型的請求體
app.use(express.urlencoded({extended: false}));
// 開放靜態資源(uploads)uploads 文件夾要放上傳的圖片
app.use(express.static('uploads'));

JWT身份認證

  • J: json
  • W:web
  • T:token

就是一種前后端分離模式使用的身份認證方式。

原理圖

在這里插入圖片描述

實現身份認證

想要完成jwt方式的身份認證,需要一下兩個第三方模塊

  • express-jwt 用于解密token字符串,還可以控制哪些接口需要身份認證。
  • jsonwebtoken 用于加密token字符串
1、登錄的接口,要給客戶端返回token
2、控制其他接口,必須攜帶正確的token才能訪問
3、其他需要權限的接口中,能夠使用token中保存的數據(用戶名)
4、如果身份認證失敗,服務器要響應 {status: 1, message: '身份認證失敗!'}

登錄成功之后,生成token

在login.js中

  • 加載jsonwebtoken模塊
  • 使用該模塊的 sign 方法生成token加密串
  • 返回給客戶端的時候,要在加密串前面加上 “Bearer

參考代碼:

/*          login.js  */
// 加載jsonwebtoken模塊(用于生成token加密串)
const jwt = require('jsonwebtoken');// 登錄的接口
router.post('/login', async (req, res) => {// 假設賬號是 admin,密碼是 111111if (req.body.username === 'admin' && req.body.password === '111111') {// 登錄成功res.json({status: 0,message: '登錄成功',// token: 'Bearer ' + jwt.sign(要保存的信息, 秘鑰, 配置項)// 生成的token前面必須有Bearer,還有一個空格。否則一會token不能正常的解密token: 'Bearer ' + jwt.sign({username: 'admin', age: 20}, 'bigevent-9760', {expiresIn: 2*60*1000})});}
});

使用express-jwt控制 以 /my 開頭的接口,必須加入token才能訪問

在 app.js 中

  • 加載 express-jwt 模塊
  • 配置中間件,指定哪些接口不需要身份認證
// 使用express-jwt模塊,控制 以 /my 開頭的接口,需要正確的token才能訪問
const expressJWT = require('express-jwt');
// 下面一行代碼的意思是,除了以 /api 開頭的接口,其他所有接口都需要身份認證才能訪問
app.use(  expressJWT({ secret: 'bigevent-9760' }).unless({path: /^\/api/})  );

使用Postman來測試

  • 請求的時候,header頭如果沒有token,是否報錯了
  • 請求的時候,header頭如果有token,是否可以正常訪問

使用錯誤中間件統一處理身份認證失敗的情況

在 app.js 最后的位置,加一個錯誤中間件

// 錯誤中間件,統一處理tokne的問題
app.use((err, req, res, next) => {// 真的token問題,做判斷if (err.name === 'UnauthorizedError') {console.log(err.message);res.json({status: 1,message: '身份認證失敗!'});}
});

在其他路由中,可以使用req.user對象,獲取到token中保存的數據

登錄和注冊

創建數據庫、數據表

創建 big-event數據庫

創建user表:

在這里插入圖片描述

注冊

  • 接收post請求體
  • 寫insert語句,完成添加
let r = await db('insert into user set ?', req.body);
if (r.affectedRows > 0) {res.json({status: 0,message: '注冊成功'});
} else {res.json({status: 0,message: '注冊失敗'});
}

這個代碼,不夠嚴謹。如果SQL出現一點點問題,就會報一大段錯誤,并且也不會做下響應。

使用try…catch 來解決問題

修改后的代碼如下:

// 注冊的接口
router.post('/reguser', async (req, res) => {// 獲取post請求體(也就是用戶提交的賬號和密碼)// 添加到 user 表 中// console.log(req.body); // { username: 'admin', password: '111111' }try {let r = await db('insert into user set ?', req.body);res.json({status: 0,message: '注冊成功'});} catch (err) {console.log(err.message); // 輸出這個信息,是為了程序員排錯res.json({status: 1,message: '注冊失敗'});}
});

思考:

  1. 除了try…catch… 你還能想到其他辦法嗎?
  2. 其他接口也需要使用try…catch完成SQL的執行,有沒有統一的解決辦法?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/247986.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/247986.shtml
英文地址,請注明出處:http://en.pswp.cn/news/247986.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

1.Consul 簡介和環境搭建

1.什么是 Consul Consul 是 service mesh(服務網格)的一個解決方案,它提供了諸如服務發現,配置和隔離等功能的一整套控制平面(control plane)。開發人員可以根據需要單獨使用這些功能點,也可以將他們整合成為一個完整的service mesh。Consul …

Node — 第八天 (大事件項目接口實現二)

如何處理MySQL的錯誤 MySQL的錯誤信息,可以通過err來獲取。這是沒有問題的。 但是,我們加入了Promise,Promise中的錯誤,在外部是獲取不到的,只能使用Promise相關方法來獲取錯誤信息。 解決方法一 使用 JS原生的 tr…

在local模式下的spark程序打包到集群上運行

一、前期準備 前期的環境準備,在Linux系統下要有Hadoop系統,spark偽分布式或者分布式,具體的教程可以查閱我的這兩篇博客: Hadoop2.0偽分布式平臺環境搭建 Spark2.4.0偽分布式環境搭建 然后在spark偽分布式的環境下必須出現如下八…

Effective Objective-C 2.0 初讀小結

1.對于OC中的對象聲明例如NSObject *obj1 [NSObject new];, obj1這個指針變量是分配在棧上的, 他指向的是這一個分配在堆上面的實例對象, 如果進行下面的賦值操作NSObject *obj2 obj1;,那么并沒有新生成一個實例對象, 只是在棧上分配了一個新的指針變量obj2, 而obj2和obj1指向…

APS系統對制造企業到底有多重要?看完這5點你就明白了

第一個問題:需要APS嗎? APS是否重要,不能從其所體現的軟件工具或系統角度來說,而應該從業務角度來說。對于制造工廠和車間的運行而言,計劃是核心的業務。就如同那句俗話說的,沒有規矩不成方圓,領…

Node — 第九天 (大事件項目接口實現三)

文章管理接口 設計數據表 添加文章接口 編寫接口,使用postman模擬提交formdata類型的數據 在article.js 中,加入 /add 路由 postman模擬提交formdata類型的數據 multer處理文件上傳 下載安裝multer 加載模塊 const multer require(multer) 配置上…

Python之爬蟲-段子網

Python之爬蟲-段子網 https://ishuo.cn #!/usr/bin/env python # -*- coding:utf-8 -*- import re import requestsresponse requests.get(https://ishuo.cn) data response.text print(data) r re.findall(<div class"content">(.*?)</div>,data) f…

Node — 第九天 (ES6降級 and 發布屬于自己的[第三方模塊]包)

ES6降級處理 因為 ES 6 有瀏覽器兼容性問題&#xff0c;可以使用一些工具進行降級處理&#xff0c;例如&#xff1a;babel 降級處理 babel 的使用步驟 安裝 Node.js命令行中安裝 babel配置文件 .babelrc運行命令&#xff0c;完成降級 項目初始化 (項目文件夾不能有中文) npm …

Vue — 第一天(極速入門)

基本介紹 vue是什么 目標&#xff1a;了解vue的一些基礎概念。 官方網站&#xff1a; https://cn.vuejs.org/ vue是&#xff1a;漸進式javascript框架。 兩組概念 &#xff08;1&#xff09;框架 庫。只提供一些API給開發者使用。jquery 是一個js庫框架。擁有自己的規則和…

python類和實例化

簡答介紹類和實例python是面向對象的語言&#xff0c;最主要的就是類和實例&#xff0c;類是抽象的模版創建一個類class Studen(object),class 后接類名&#xff0c;定義的類名大些字母開頭&#xff0c;object為類的繼承&#xff0c;沒有合適的繼承類用object類&#xff0c;這是…

pjsip庫分析

http://blog.chinaunix.net/space.php?uid287570&doblog&cuid728411 如果你對SIP/VoIP技術感興趣,哪希望你不要錯過:),如果你對寫出堪稱優美的Code感興趣,那么你也不可錯過:)這期間我想分析一下一個實際的協議棧的設計到實現的相關技術,算是自己的一個學習經歷記錄.最…

Vue — 第二天(v-model和過濾器)

VUE-02-v-model和過濾器 昨日反饋與回顧 代碼倉庫的問題 不要修改你克隆下來的倉庫中任意代碼&#xff0c;否則&#xff0c;下次pull時&#xff0c;可能會報錯&#xff0c;從而得到不到最新的代碼。 如果已經遇到了這個沖突&#xff1a; 解決沖突(git 中解決沖突)把關鍵代碼…

Count

題目鏈接&#xff1a;點這里 題目意思&#xff1a;令f(x)表示<x的正整數中與x互質的數的平均數*2&#xff0c;求sigma(f(i)^k),L<i<R Solution: 首先&#xff0c;我們定義\(S(x)\sum_{gcd(a,x)1}a\)&#xff0c;因為gcd(a,x)1&#xff0c;所以對于任意a&#xff0c;滿…

牛人iOS開發系列--音頻播放、錄音、視頻播放、拍照、視頻錄制

概覽 隨著移動互聯網的發展&#xff0c;如今的手機早已不是打電話、發短信那么簡單了&#xff0c;播放音樂、視頻、錄音、拍照等都是很常用的功能。在iOS中對于多媒體的支持是非常強大的&#xff0c;無論是音視頻播放、錄制&#xff0c;還是對麥克風、攝像頭的操作都提供了多套…

Vue — 第三天(計算屬性和json-server)

計算屬性 使用場景 如果一個結果需要依賴data中的數據&#xff0c;但是需要經過一些邏輯處理&#xff0c;才能得到你想要的數據。此時就可以使用計算屬性。 例如&#xff1a;要對給定的字符串做翻轉處理之后再來顯示。 <div id"app"><!-- 此處邏輯復雜 …

JQuery的ready函數與JS的onload的區別詳解

JQuery的ready函數與JS的onload的區別&#xff1a;1.執行時間window.onload必須等到頁面內包括圖片的所有元素加載完畢后才能執行。$(document).ready()是DOM結構繪制完畢后就執行&#xff0c;不必等到加載完畢。 2.編寫個數不同window.onload不能同時編寫多個&#xff0c;如果…

Vue — 第四天(components組件)

問題導入 下面的代碼是一個折疊面板的效果。 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewport" content"widthdevice-width, initial-scale1.0"><title>Docu…

iOS開發常用的RGB色值和宏

iOS中RGB常用的色值,同時可將對顏色的設置定義成宏,方便開發應用,如: // name 顏色相關 // 參數格式為&#xff1a;0xFFFFFF #define kColorWithRGB(rgbValue) \ [UIColor colorWithRed:((float)((rgbValue & 0xFF0000) >> 16)) / 255.0 \ …

防火墻綜合實驗

防火墻技術綜合實驗 一、實驗目的&#xff1a;本次實驗是將多種訪問控制列表以及防火墻部分的知識做一個匯總 二、實驗內容 A&#xff1a;Established控制列表 拓撲圖 配置步驟 1:配置各端口ip地址&#xff0c;配置登陸密碼 R4: 登陸賬號&#xff1a;ys 密碼&#xff1a;123 2:…

iOS獲取當前設備型號等信息總結 包含iPhone7和iPhone7P

#include <sys/types.h> #include <sys/sysctl.h>//獲得設備型號(NSString *)getCurrentDeviceModel {int mib[2];size_t len;char *machine;mib[0] CTL_HW;mib[1] HW_MACHINE;sysctl(mib, 2, NULL, &len, NULL, 0);machine malloc(len);sysctl(mib, 2, mac…