2dayjavascript
做業:php
3dayhtml
4day前端
mongodb 環境配置安裝vue
mongoose 操做mongod數據庫java
經常使用的服務器緩存redisnode
自動化測試react
5daylinux
瀏覽器中的 JavaScript 能夠作什麼?git
瀏覽器中的 JavaScript 不能夠作什麼?(不安全)
+訪問數據庫
+不能對文件進行操做
+對os 進行操做
+緣由 是不安全 和瀏覽器運行機制有關
在開發人員能力相同的狀況下編程語言的能力取決於什麼?
+cordova hbuilder 平臺 platform
+java java虛擬機 (運行平臺)
+php php虛擬機
+c# .net framework mono
+js 解析內核 chrome v8
JavaScript 只能夠運行在瀏覽器中嗎?
+不是
Node.js 是一個基於Chrome V8 引擎的JavaScript運行環境 王者
Node.js使用了一個事件驅動、非阻塞式I/O的模型,使其輕量又高效
Node.js的包管理工具npm,是全球最大的開源庫生態系統
第三方: 國外的
建議: 切換國內的, 淘寶國內鏡像源
nrm
安裝cnpm
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
查看是否cnpm安裝成功
cnpm -v
官網 http://nodejs.cn/
npm 插件官網:https://www.npmjs.com/
安裝包安裝
nvm安裝(有一個相似的工具:nvm)
Node Version Manager(Node版本管理工具)
默認安裝結束以後,默認路徑: C:\Users\xxx\AppData\Roaming\nvm
nvm安裝教程博客:https://blog.csdn.net/qq_32682137/article/details/82684898
問題: 若是有的同窗,任意目錄不能使用nvm,只有在nvm安裝目錄下才能使用,那麼就是環境變量有問題?
在高級環境變量中的系統變量中建立兩個變量
1. NVM_HOME 變量名: NVM_HOME 變量值: nvm安裝目錄路徑 2. NVM_SYMLINK 變量名: NVM_SYMLINK 變量值: Node.js的安裝目錄
在系統變量的path路徑中將上面建立的變量引用進來
;%NVM_HOME%%NVM_SYMLINK%添加到系統變量 pth路徑的後面
切記: 不要將path路徑刪除了
nvm使用
nvm list 列出當前電腦中全部的Node.js的版本 nvm install version 安裝某一個版本的Node.js , 舉例: 安裝10.12.0版本 nvm install 10.12.0 nvm use version 切換某一個Node.js版本 切換後切記: 要確認Node運行十分正常 node -v npm -v 若是以上二者輸出正常,那麼久切換成功了 若是不正常呢?換版本下載安裝( 必須在8.9+ 以上)
注意:全部別名必須在新版本的 PowerShell (linux系統)中使用
電腦:
cmd裏面用的叫作 DOS命令
cmd終端喚醒: win鍵 + R , 輸入cmd 回車
mkdir 建立目錄
dir 列出當前目錄的列表
cls 清空終端命令
del 刪除某一個文件
git / powershell 用的是linux命令
mkdir 建立目錄
ls 查看當前目錄列表
clear 清空當前控制檯
rm -rf 文件名稱 刪除某一個文件或是目錄
兩種類型的命令中, cd是一個意思
環境變量丟失
目的能夠在任何地方調起node命令
藉助第三方工具實現:
nodemon 【 推薦 】
cnpm i nodemon -g
nodemon 文件名稱
supervisor
cnpm i supervisor -g
supervisor 文件名稱
前端模塊化:AMD,CMD,Commonjs
Node 應用由模塊組成,採用 CommonJS 模塊規範。
每一個文件就是一個模塊,有本身的做用域。在一個文件裏面定義的變量、函數、類,都是私有的,對其餘文件不可見。
CommonJS規範規定,每一個模塊內部,module變量表明當前模塊。這個變量是一個對象,它的exports屬性(即module.exports)是對外的接口。加載某個模塊,實際上是加載該模塊的module.exports屬性。
var x = 5; var addX = function (value) { return value + x; }; module.exports.x = x; module.exports.addX = addX;
require方法用於加載模塊。
var example = require('./example.js'); console.log(example.x); // 5 console.log(example.addX(1)); // 6
const process = require('process') const path = require('path') console.log(process.version) console.log(path.resolve('../'))
const request=require("request"); console.log(request) request.get('http://api.douban.com/v2/movie/in_theaters', (err, response, body) => { if (!err) { // console.log(body); console.log(JSON.parse(body)) } else { console.log(err); } })
安裝:無需安裝
查看當前版本:
$ npm -v
更新:
$ npm install npm@latest -g
初始化工程
$ npm init $ npm init --yes 默認配置
安裝包
使用npm install會讀取package.json文件來安裝模塊。安裝的模塊分爲兩類
dependencies和devDependencies,分別對應生產環境須要的安裝包和開發環境須要的安裝包。
$ npm install $ npm install <package_name> $ npm install <package_name> --save $ npm install <package_name> --save-dev
更新模塊
$ npm update
卸載模塊
$ npm uninstall <package_name> $ npm uninstall --save lodash
配置npm源
臨時使用, 安裝包的時候經過--registry參數便可
$ npm install express --registry https://registry.npm.taobao.org
全局使用
$ npm config set registry https://registry.npm.taobao.org // 配置後可經過下面方式來驗證是否成功 npm config get registry // 或 npm info express
cnpm 使用
// 安裝cnpm npm install -g cnpm --registry=https://registry.npm.taobao.org // 使用cnpm安裝包 cnpm install express
node 經常使用內置api
(1) URL 網址解析
解析URL相關網址信息
url.parse(urlString[, parseQueryString[, slashesDenoteHost]])
url.format(urlObject)
url.resolve(from, to)
(2) QueryString 參數處理
querystring.escape(str)
querystring.unescape(str)
querystring.parse(str[, sep[, eq[, options]]])
querystring.stringify(obj[, sep[, eq[, options]]])
(3) HTTP 模塊概要
http.createServer([options][, requestListener])
http.get(options[, callback])
簡易的爬蟲
代理跨域處理
(4) 事件 events 模塊
(5) 文件fs模塊
打印目錄樹
(6) Stream 流模塊
歌詞播放
音樂下載
(8) request 方法
二、Node.js 基礎應用
一、應用 HTTP 模塊編寫一個小爬蟲工具
(1) 利用爬蟲獲取「拉勾網」首頁列表數據
(2) 經過 npm 安裝 cheerio 模塊得到數據
二、後端表單的提交
要求:
(1) 應用 request post 模擬提交表單
Node中文件讀取的方式主要有:
fs.readFile(file[, options], callback(error, data))
fs.readFile('c:\\demo\1.txt', 'utf8', (err, data) => { if (err) throw err; console.log(data); });
fs.readFileSync(file[, options])
try { const data = fs.readFileSync('c:\\demo\1.txt', 'utf8'); console.log(data); } catch(e) { // 文件不存在,或者權限錯誤 throw e; }
fs.createReadStream(path[, options])
const stream = fs.createReadStream('c:\\demo\1.txt'); let data = '' stream.on('data', (trunk) => { data += trunk; }); stream.on('end', () => { console.log(data); });
因爲Windows平臺下默認文件編碼是GBK,在Node中不支持,能夠經過iconv-lite解決
const readline = require('readline'); const fs = require('fs'); const rl = readline.createInterface({ input: fs.createReadStream('sample.txt') }); rl.on('line', (line) => { console.log('Line from file:', line); });
Node中文件寫入的方式主要有:
fs.writeFile(file, data[, options], callback(error))
fs.writeFile('c:\\demo\a.txt', new Date(), (error) => { console.log(error); });
fs.writeFileSync(file, data[, options])
try { fs.writeFileSync('c:\\demo\a.txt', new Date()); } catch (error) { // 文件夾不存在,或者權限錯誤 console.log(error); }
fs.createWriteStream(path[,option])
var streamWriter = fs.createWriteStream('c:\\demo\a.txt'); setInterval(() => { streamWriter.write(`${new Date}\n`, (error) => { console.log(error); }); }, 1000);
console.time('sync'); try { var data = fs.readFileSync(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4')); // console.log(data); } catch (error) { throw error; } console.timeEnd('sync'); console.time('async'); fs.readFile(path.join('C:\\Users\\iceStone\\Downloads', 'H.mp4'), (error, data) => { if (error) throw error; // console.log(data); }); console.timeEnd('async');
使用了回調函數的異步處理
---- getAsync("fileA.txt", function(error, result){ if(error){// 取得失敗時的處理 throw error; } // 取得成功時的處理 }); ---- <1> 傳給回調函數的參數爲(error對象, 執行結果)錯誤優先處理
使用了回調函數的異步處理
---- var promise = getAsyncPromise("fileA.txt"); promise.then(function(result){ // 獲取文件內容成功時的處理 }).catch(function(error){ // 獲取文件內容失敗時的處理 }); ---- <1> 返回promise對象
var promise = new Promise(function(resolve, reject) { // 異步處理 // 處理結束後、調用resolve 或 reject resolve('成功處理') reject('錯誤處理') });
new Promise(fn)
resolve(處理結果值)
reject(Error對象)
function asyncFunction() { return new Promise(function (resolve, reject) { setTimeout(function () { resolve('Async Hello world'); }, 16); }); } asyncFunction().then(function (value) { console.log(value); // => 'Async Hello world' }).catch(function (error) { console.log(error); });
用new Promise 實例化的promise對象有如下三個狀態。
promise對象的狀態,從Pending轉換爲Fulfilled或Rejected以後, 這個promise對象的狀態就不會再發生任何變化。
也就是說,Promise與Event等不一樣,在.then 後執行的函數能夠確定地說只會被調用一次。
另外,Fulfilled和Rejected這兩個中的任一狀態均可以表示爲Settled(不變的)。
Settled
resolve(成功) 或 reject(失敗)。
從Pending和Settled的對稱關係來看,Promise狀態的種類/遷移是很是簡單易懂的。
當promise的對象狀態發生變化時,用.then 來定義只會被調用一次的函數。
在文件操做的過程當中,都必須使用物理路徑(絕對路徑),path模塊提供了一系列與路徑相關的 API
console.log('join用於拼接多個路徑部分,並轉化爲正常格式'); const temp = path.join(__dirname, '..', 'lyrics', './友誼之光.lrc'); console.log(temp); console.log('獲取路徑中的文件名'); console.log(path.basename(temp)); console.log('獲取路徑中的文件名並排除擴展名'); console.log(path.basename(temp, '.lrc')); console.log('===================================='); console.log('獲取不一樣操做系統的路徑分隔符'); console.log(process.platform + '的分隔符爲 ' + path.delimiter); console.log('通常用於分割環境變量'); console.log(process.env.PATH.split(path.delimiter)); console.log('===================================='); console.log('獲取一個路徑中的目錄部分'); console.log(path.dirname(temp)); console.log('===================================='); console.log('獲取一個路徑中最後的擴展名'); console.log(path.extname(temp)); console.log('===================================='); console.log('將一個路徑解析成一個對象的形式'); const pathObject = path.parse(temp); console.log(pathObject); console.log('===================================='); console.log('將一個路徑對象再轉換爲一個字符串的形式'); // pathObject.name = '我終於失去了你'; pathObject.base = '我終於失去了你.lrc'; console.log(pathObject); console.log(path.format(pathObject)); console.log('===================================='); console.log('獲取一個路徑是否是絕對路徑'); console.log(path.isAbsolute(temp)); console.log(path.isAbsolute('../lyrics/愛的代價.lrc')); console.log('===================================='); console.log('將一個路徑轉換爲當前系統默認的標準格式,並解析其中的./和../'); console.log(path.normalize('c:/develop/demo\\hello/../world/./a.txt')); console.log('===================================='); console.log('獲取第二個路徑相對第一個路徑的相對路徑'); console.log(path.relative(__dirname, temp)); console.log('===================================='); console.log('以相似命令行cd命令的方式拼接路徑'); console.log(path.resolve(temp, 'c:/', './develop', '../application')); console.log('===================================='); console.log('獲取不一樣平臺中路徑的分隔符(默認)'); console.log(path.sep); console.log('===================================='); console.log('容許在任意平臺下以WIN32的方法調用PATH對象'); // console.log(path.win32); console.log(path === path.win32); console.log('===================================='); console.log('容許在任意平臺下以POSIX的方法調用PATH對象'); console.log(path === path.posix);
官網:http://www.expressjs.com.cn/
安裝
$ npm install express --save
快速開始
const express = require('express') const app = express() app.get('/', (req, res) => res.send('Hello World!')) app.listen(3000, () => console.log('Example app listening on port 3000!'))
let express=require('express') let router=express.Router() // 該路由使用的中間件 router.use((req,res,next)=>{ next() }); // 定義網站主頁的路由 router.post('/addFood', function(req, res) { console.log('hahaha') // res.send('這裏是admin的登陸'); }); // 定義 about 頁面的路由 router.post('/regist', function(req, res) { res.send('這裏是admin的註冊側'); }); module.exports = router; app.use('/admin',admin)
get req.query post req.body body-parser 設置中文格式 res.set('Content-Type','text/plain,charset=utf8')
app.use(express.static('public')) app.use('/static', express.static('public')) app.use('/static', express.static(path.join(__dirname, 'public')))
在
Mongodb
官網下載最新版本的Mongodb下載地址下載
msi
的window
安裝包,能夠裝到C盤或者D盤目錄下配置
因爲我是安裝在D盤的環境下
D:\Program Files (x86)\MongoDB\Server\3.2\bin因此在bin文件夾下找到mongod.exe命令,而後經過管理員執行
mongod --dbpath x路徑x
,路徑能夠是任何地方,我這裏選擇在D盤的MongoDB目錄下,固然路徑不要包含特殊的字符串,好比Program Files (x86)
也不行mongod --dbpath D:\mongodb\data\db
命令行
通過上面的配置以後,就能夠返回bin目錄下找到
mongo.exe
命令,並管理員下執行,就能夠出現mongodb的命令行模式D:\Program Files (x86)\MongoDB\Server\3.2\bin
而後就可使用下面的命令來測試了
db.help()//幫助 db.stats()//統計顯示數據庫
show dbs檢查當前選擇的數據庫
db添加數據庫
數據庫名爲數據庫建立的名字,使用該命令後會默認切換到對應的數據庫,而且在數據庫中添加選項,數據庫信息才顯示,若是默認就有該數據庫,那就是切換到對應的數據庫裏面
use 數據庫名刪除數據庫
先切換到對應的數據庫,而後再執行
db.dropDatabase()
刪除該數據庫use 數據庫名 //switched to db 數據庫名 db.dropDatabase()顯示集合
用一下命令能夠檢查建立的集合
show collections添加集合
在建立完數據庫以後,咱們就能夠建立集合
db.createCollection(集合名字name,設置參數options[對象類型])name是要建立的集合的名稱。 options是一個文檔,用於指定集合的配置
參數 類型 描述
name String 要建立的集合的名稱
options Document (可選)指定有關內存大小和索引的選項
options參數是可選的,所以只須要指定集合的名稱。 如下是可使用的選項列表:字段 類型 描述
capped Boolean (可選)若是爲true,則啓用封閉的集合。上限集合是固定大小的集合,它在達到其最大大小時自動覆蓋其最舊的條目。 若是指定true,則還須要指定size參數。
autoIndexId Boolean (可選)若是爲true,則在_id字段上自動建立索引。默認值爲false。
size 數字 (可選)指定上限集合的最大大小(以字節爲單位)。 若是capped爲true,那麼還須要指定此字段的值。
max 數字 (可選)指定上限集合中容許的最大文檔數。
因爲option是可選,咱們也能夠不帶配置項建立集合db.createCollection("mycollection")刪除集合
db.collection.drop()
用於從數據庫中刪除集合db.集合名.drop()好比咱們能夠測試如下操做
db.createCollection("wscats")//建立名爲wscats的集合 show collections//顯示該數據庫全部集合 wscats db.wscats.drop()//刪除名爲wscats的集合查看文檔
最簡單查看文檔的方法就是
find()
,會檢索集合中全部的文檔結果db.集合名.find()要以格式化的方式顯示結果,可使用
pretty()
方法。db.集合名.find().pretty()1.固值尋找
尋找age集合裏面全部含有屬性值爲wscats的文檔結果,至關於
where name = 'wscats'
db.age.find({name:"wscats"})2.範值尋找
操做 語法 示例 等效語句
相等 {:}db.age.find({"name":"wscats"}).pretty()
where name = 'wscats'
小於 {:{$lt:}}db.age.find({"likes":{$lt:50}}).pretty()
where likes < 50
小於等於 {:{$lte:}}db.age.find({"likes":{$lte:50}}).pretty()
where likes <= 50
大於 {:{$gt:}}db.age.find({"likes":{$gt:50}}).pretty()
where likes > 50
大於等於 {:{$gte:}}db.age.find({"likes":{$gte:50}}).pretty()
where likes >= 50
不等於 {:{$ne:}}db.age.find({"likes":{$ne:50}}).pretty()
where likes != 503.AND和OR尋找
AND
在find()方法中,若是經過使用
,
將它們分開傳遞多個鍵,則mongodb將其視爲AND條件。 如下是AND的基本語法尋找
_id
爲1而且name
爲wscats的全部結果集db.age.find( { $and: [ {"_id": 1}, {"name": "wscats"} ] } )OR
在要根據OR條件查詢文檔,須要使用
$or
關鍵字。如下是OR條件的基本語法尋找
name
爲corrine或者name
爲wscats的全部結果集db.age.find( { $or: [ {"name": "corrine"}, {「name「: "wscats"} ] } )AND和OR等結合
至關於語句
where title = "wscats" OR ( title = "corrine" AND _id < 5)
db.age.find({ $or: [{ "title": "wscats" }, { $and: [{ "title": "corrine" }, { "_id": { $lte: 5 } }] }] })插入文檔
文檔的數據結構和JSON基本同樣。
全部存儲在集合中的數據都是BSON格式。
BSON是一種類json的一種二進制形式的存儲格式,簡稱Binary JSON。要將數據插入到mongodb集合中,須要使用mongodb的
insert()
或save()
方法。db.集合名.insert(document)好比咱們能夠插入如下數據
db.wscats.insert({ _id: 100, title: 'MongoDB Tutorials', description: 'node_tutorials', by: 'Oaoafly', url: 'https://github.com/Wscats/node-tutorial', tags: ['wscat','MongoDB', 'database', 'NoSQL','node'], num: 100, })也能夠支持插入多個,注意傳入的是數組形式
db.wscats.insert([{ _id: 100, title: ‘Hello’ },{ _id: 101, title: ‘World’ }])在插入的文檔中,若是不指定_id參數,那麼mongodb會爲此文檔分配一個惟一的ObjectId
要插入文檔,也可使用db.post.save(document)
。若是不在文檔中指定_id,那麼save()
方法將與insert()
方法同樣自動分配ID的值。若是指定_id,則將以save()方法的形式替換包含**_id**的文檔的所有數據。db.wscats.save({ _id: 111, title: 'Oaoafly Wscats', })更新文檔
1.update()方法
尋找第一條title爲wscats的值,而且更新值title爲corrine和age爲12
db.age.update({ 'title': 'wscats' }, { $set: { 'title': 'corrine', 'age': 12 } })默認狀況下,mongodb只會更新一個文檔。要更新多個文檔,須要將參數
multi
設置爲true,還能夠配合find方法裏面的各類複雜條件判斷來篩選結果,而後更新多個文檔尋找全部title爲wscats的值,而且更新值title爲corrine和age爲12
db.age.update({ 'title': 'wscats' }, { $set: { 'title': 'corrine', 'age': 12 } }, { multi: true })2.save()方法
將
_id
主鍵爲3的文檔,覆蓋新的值,注意_id
爲必傳db.age.save({ '_id':3, 'title': 'wscats' })刪除文檔
刪除主鍵
_id
爲3的文檔,默認是刪除多條db.age.remove({ '_id':3 })建議在執行
remove()
函數前先執行find()
命令來判斷執行的條件是否正確若是你只想刪除第一條找到的記錄能夠設置justOne爲1,以下所示
db.age.remove({...},1)所有刪除
db.age.remove({})Limit與Skip方法
Limit
若是你須要在mongodb中讀取指定數量的數據記錄,可使用mongodb的Limit方法,
limit()
方法接受一個數字參數,該參數指定從mongodb中讀取的記錄條數。db.age.find().limit(數量)Skip
咱們除了可使用
limit()
方法來讀取指定數量的數據外,還可使用skip()
方法來跳過指定數量的數據,skip方法一樣接受一個數字參數做爲跳過的記錄條數。db.age.find().limit(數量).skip(數量) //skip()方法默認值爲0因此咱們在實現分頁的時候就能夠用limit來限制每頁多少條數據(通常固定一個值),用skip來決定顯示第幾頁(一個有規律變更的值)
排序
在mongodb中使用使用
sort()
方法對數據進行排序,sort()
方法能夠經過參數指定排序的字段,並使用1和-1來指定排序的方式,其中1爲升序排列,而-1是用於降序排列。1 升序排列
-1 降序排列db.集合名.find().sort({鍵值(屬性值):1})把
age
集合表從新根據_id
主鍵進行降序排列db.age.find().sort({ "_id": -1 })Node.js鏈接
安裝mongodb的模塊
npm install mongodb1.鏈接數據庫
var MongoClient = require('mongodb').MongoClient; //結尾是選擇數據庫名 var DB_CONN_STR = 'mongodb://localhost:27017/wscats'; MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("鏈接成功!"); });2.查詢數據
注意查詢回來的結果須要toArray來遍歷處理
var MongoClient = require('mongodb').MongoClient; var DB_CONN_STR = 'mongodb://localhost:27017/wscats'; MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("鏈接成功!"); //選中age集合,並用find方法把結果集拿回來進行處理 db.collection("age").find({title: "cba"}).toArray(function(err, result) { if (err) { console.log('Error:' + err); return; } console.log(result); }); });通過測試,讀取大於100條的時候會出現報錯官網解釋,能夠嘗試用
forEach
代替db.collection('pokemon').find({}) .forEach(function(item){ console.log(item) })查詢ID
查詢自動生成的
ObjectId
var ObjectId = require('mongodb').ObjectId; let _id = ObjectId("5bcae50ed1f2c2f5e4e1a76a"); db.collection('xxx').find({ "_id": _id }).forEach(function (item) { console.log(item) })3.插入數據
insert函數第一個參數是須要插入的值(能夠一個也能夠多個),第二個參數是接受一個回調函數,當值插入成功後回返回插入值得一些關鍵信息,好比
_id
var MongoClient = require('mongodb').MongoClient; var DB_CONN_STR = 'mongodb://localhost:27017/wscats'; MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("鏈接成功!"); const db = client.db("demo"); db.collection("age").insert([ { title: "插入的值A" }, { title: "插入的值B" } ], function(err, result) { if (err) { console.log('Error:' + err); return; } console.log(result) }) });4.更新數據
注意若是不加$set就是徹底替換原來的那份(沒有設置的屬性值將會丟失),加上$set則只是更新對應的屬性值,其他不作改變
var MongoClient = require('mongodb').MongoClient; var DB_CONN_STR = 'mongodb://localhost:27017/wscats'; MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("鏈接成功!"); db.collection("age").update({ "_id": 1 }, { $set: { title: "你好,世界", skill: "js" } }, function(err, result) { if (err) { console.log('Error:' + err); return; } //console.log(result); }); });5.刪除數據
var MongoClient = require('mongodb').MongoClient; var DB_CONN_STR = 'mongodb://localhost:27017/wscats'; MongoClient.connect(DB_CONN_STR, function(err, db) { console.log("鏈接成功!"); db.collection("age").remove({ "_id": 1 }, function(err, result) { if (err) { console.log('Error:' + err); return; } //console.log(result); //關閉數據庫 db.close(); }); });6.關閉數據庫
db.close();封裝自定義模塊
新建
mongo.js
寫入如下代碼,封裝自定義模塊,方便其餘路由複用,注意assert
是node自帶的斷言模塊,用於測試代碼參考
const MongoClient = require('mongodb').MongoClient; const assert = require('assert'); const url = 'mongodb://localhost:27017'; const dbName = 'shop'; function query(callback) { MongoClient.connect(url, function(err, client) { assert.equal(null, err); console.log("Connected successfully to server"); const db = client.db(dbName); callback(db); client.close(); }); } module.exports = { query }在路由文件中引入和使用
var mongo = require('./mongo.js') router.post('/addproduct', function(req, res, next) { mongo.query(function(db) { db.collection("product").insertMany([req.body], function(err, result) { console.log("Inserted 1 document into the collection"); res.send('respond with a resource'); }); }) });
- 下載mongoose
npm install mongoose --save
- 鏈接數據庫
var mongoose = require('mongoose'); mongoose.connect('mongodb://localhost:27017/1823'); var db = mongoose.connection;// 獲取鏈接對象進行監聽 db.on('error',(err)=>{ console.log('鏈接錯誤') }); db.on('open', function() { console.log('鏈接ok') });
- 建立schema對象
var UserSchema = new mongoose.Schema({ name: String, pass: String, test:String });
- 將schema轉化爲數據模型
let user = mongoose.model('user', UserSchema); //參數1 是集合的名字 與數據模型關聯的schema對象
- 經過數據模型執行查詢操做
<!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>socket.io</title> <script src="socket.io.js" charset="utf-8"></script> </head> <body> <h1>gp6 交流區</h1> <div id="content" name="name" style="overflow-y: scroll; width: 400px; height: 300px; border: solid 1px #000"></div> <br /> <div> <input type="text" id="msg" style="width: 200px;"> </div> <button id="submit">提交</button> <script> var socket = io.connect('http://10.9.164.98:8081'); const content = document.getElementById('content') document.querySelector('#submit') .addEventListener('click', function () { var msg2 = msg.value socket.emit('receive', msg2) msg.value = '' content.innerHTML += msg2 + '<br/>' }, false) socket.on('message', function(msg){ content.innerHTML += msg + '<br/>' }) </script> </body> </html>
server.js
var express = require('express'); var app = express(); var server = require('http').Server(app); var io = require('socket.io')(server); app.use(express.static(__dirname + '/client')) io.on('connection', function (socket) { setInterval(function () { socket.emit('list', 'abc') }, 1000) socket.broadcast.emit('list', 'test'); socket.on('backend', (msg) => { console.log(msg); }) socket.on('receive', (msg) => { socket.broadcast.emit('message', msg); }) }); server.listen(8081, '10.9.164.98');
serverCode
const net = require('net') const server = new net.createServer() let clients = {} let clientName = 0 server.on('connection', (client) => { client.name = ++clientName clients[client.name] = client client.on('data', (msg) => { // console.log('客戶端傳來:' + msg); broadcast(client, msg.toString()) }) client.on('error', (e) => { console.log('client error' + e); client.end() }) client.on('close', (data) => { delete clients[client.name] console.log(client.name + ' 下線了'); }) }) function broadcast(client, msg) { for (var key in clients) { clients[key].write(client.name + ' 說:' + msg) } } server.listen(9000)
clientCode
var net = require('net') const readline = require('readline') var port = 9000 var host = '127.0.0.1' var socket = new net.Socket() socket.setEncoding = 'UTF-8' socket.connect(port, host, () => { socket.write('hello.') }) socket.on('data', (msg) => { console.log(msg.toString()) say() }) socket.on('error', function (err) { console.log('error' + err); }) socket.on('close', function () { console.log('connection closeed'); }) const r1 = readline.createInterface({ input: process.stdin, output: process.stdout }) function say() { r1.question('請輸入:', (inputMsg) => { if (inputMsg != 'bye') { socket.write(inputMsg + '\n') } else { socket.destroy() r1.close() } }) }
const ws = new WebSocket('ws://localhost:8080/') ws.onopen = () => { ws.send('你們好') } ws.onmessage = (msg) => { const content = document.getElementById('content') content.innerHTML += msg.data + '<br/>' } ws.onerror = (err) => { console.log(err); } ws.onclose = () => { console.log('closed~'); } ws.send(msg2)
server.js
const WebSocket = require('ws') const ws = new WebSocket.Server({ port: 8080 }) let clients = {} let clientName = 0 ws.on('connection', (client) => { client.name = ++clientName clients[client.name] = client client.on('message', (msg) => { broadcast(client, msg) }) client.on('close', () => { delete clients[client.name] console.log(client.name + ' 離開了~') }) }) function broadcast(client, msg) { for (var key in clients) { clients[key].send(client.name + ' 說:' + msg) } }
vue 和 react 介紹
http 請求的無狀態性
// 1.產生公鑰和私鑰 // 產生私鑰 openssl genrsa -out ./private_key.pem 1024 1024 表明私鑰長度 // 產生公鑰 openssl rsa -in ./private_key.pem -pubout -out ./public_key.pem let private_key=fs.readFileSync(path.join(__dirname,'./private_key.pem')) let public_key=fs.readFileSync(path.join(__dirname,'./public_key.pem')) var token = jwt.sign(palyload, private_key,{ algorithm: 'RS256'}); console.log(token) let token='eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpZCI6IueUqOaIt2lkIiwiaWF0IjoxNTUxMTUyNzk1fQ.TI_xDBvObHGAH7EV40WWpQemm5nx077Gdjq-pzDx0NWN5YFd40S7XcLmgoDdYscLM7vMOP0c7z1l83JUixqk7IBjBCU-tMNo_G5_-LGkQjV3vDYq_3TkXTl42lgmFA-EBey7W6W1PgPfYlowyHAyp-07hXaMRevgVkXm2lPEFXo' var decoded = jwt.verify(token, public_key);
const jwt=require('jsonwebtoken') const scrict='sdjfksdjflajflasjflasjflksf' function creatToken(palyload){ // 產生token palyload.ctime=Date.now() return jwt.sign(palyload,scrict) } function checkToken(token){ return new Promise((resovle,reject)=>{ jwt.verify(token,scrict,(err,data)=>{ if(err){ reject('token 驗證失敗')} resovle(data) }) }) } module.exports={ creatToken,checkToken }
const cookieParse=require('cookie-parser') const session = require('express-session') app.use(session({ secret: 'hubwizApp', //爲了安全性的考慮設置secret屬性 cookie: {maxAge: 60 * 1000 * 60 * 24 }, //設置過時時間 resave: true, // 即便 session 沒有被修改,也保存 session 值,默認爲 true saveUninitialized: false, //不管有沒有session cookie,每次請求都設置個session cookie ,默認給個標示爲 connect.sid }));
登陸成功
req.session.sign = true; req.session.name = us;
須要驗證的接口判斷是否存在
註銷session
app.get('/out', function(req, res){ req.session.destroy(); res.redirect('/'); })
npm install multer
//引用express並配置 var express = require("express"); var app = express(); app.listen(3000);
var multer = require('multer'); /*var upload = multer({ //若是用這種方法上傳,要手動添加文明名後綴 //若是用下面配置的代碼,則能夠省略這一句 dest: 'uploads/' })*/
filename
屬性定製文件保存的格式屬性值 | 用途 |
---|---|
destination |
設置資源的保存路徑。注意,若是沒有這個配置項,默認會保存在/tmp/uploads 下。此外,路徑須要本身建立 |
filename |
設置資源保存在本地的文件名 |
var storage = multer.diskStorage({ //設置上傳後文件路徑,uploads文件夾會自動建立。 destination: function(req, file, cb) { cb(null, './uploads') }, //給上傳文件重命名,獲取添加後綴名 filename: function(req, file, cb) { var fileFormat = (file.originalname).split("."); //給圖片加上時間戳格式防止重名名 //好比把 abc.jpg圖片切割爲數組[abc,jpg],而後用數組長度-1來獲取後綴名 cb(null, file.fieldname + '-' + Date.now() + "." + fileFormat[fileFormat.length - 1]); } }); var upload = multer({ storage: storage });
upload.single('xxx')
,xxx與表單中的name屬性的值對應bodyParser
模塊處理app.post('/upload-single', upload.single('logo'), function(req, res, next) { console.log(req.file) console.log('文件類型:%s', req.file.mimetype); console.log('原始文件名:%s', req.file.originalname); console.log((req.file.originalname).split(".")) console.log('文件大小:%s', req.file.size); console.log('文件保存路徑:%s', req.file.path); res.send({ ret_code: '0' }); });
multiple="multiple"
屬性值,此時就能夠在選圖的時候多選了,固然也能夠並列多個file輸入框(不推薦多個上傳圖片輸入框),這樣體驗會很差<input type="file" name="logo" multiple="multiple" />
後端也須要相應的改變
app.post('/upload-single', upload.single('logo'), function(req, res, next) { //upload.single('logo')變爲upload.array('logo', 2),數字表明能夠接受多少張圖片 app.post('/upload-single', upload.array('logo', 2), function(req, res, next) {
若是不想有圖片數量上傳限制,咱們能夠用upload.any()
方法
app.post('/upload-single', upload.any(), function(req, res, next) { res.append("Access-Control-Allow-Origin","*"); res.send({ wscats_code: '0' }); });
<form action="http://localhost:3000/upload-single" method="post" enctype="multipart/form-data"> <h2>單圖上傳</h2> <input type="file" name="logo"> <input type="submit" value="提交"> </form>
<form id="uploadForm"> <p>指定文件名: <input type="text" name="filename" value="" /></p> <p>上傳文件: <input type="file" name="logo" /></ p> <input type="button" value="上傳" onclick="doUpload()" /> </form>
FormData
對象,是可使用一系列的鍵值對來模擬一個完整的表單,而後使用XMLHttpRequest
發送這個"表單"
注意點
<form>
標籤添加enctype="multipart/form-data"
屬性。<form>
表單構造的FormData對象,且已經聲明瞭屬性enctype="multipart/form-data"
,因此這裏設置爲false上傳後,服務器端代碼須要使用從查詢參數名爲logo獲取文件輸入流對象,由於<input>
中聲明的是name="logo"
function doUpload() { $.ajax({ url: 'http://localhost:3000/upload-single', type: 'POST', cache: false, //沒必要須 data: new FormData($('#uploadForm')[0]), processData: false,//必須 contentType: false,//必須 success: function(data) { console.log(data) } }) }
Mocha('摩卡'),誕生於2011年,如今比較流行的JavaScript測試框架之一,能夠運行於Node環境和瀏覽器環境
測試框架:能夠運行測試的工具。經過他,能夠爲JavaScript應用 添加測試,從而保證代碼質量
使用npm 全局安裝
$ npm install --global mocha
項目依賴 局部安裝
$ npm isntall mocha
全局安裝chai
npm install chai -g
遞歸執行
$ mocha test --recursive