前言
作為程式猿,可以沒有女朋友(好像也只能接收找不到的現實),但絕對不能沒有格子衫、護髮素····和對原生的摯愛,今天,我們們就來手寫一個簡單的node伺服器吧
目標
- 實現伺服器的處理請求,返回響應
- 實現不同請求方式的處理不同
- 進階:實現表單提交檔案
實現要點
- 伺服器本質上就是一臺電腦,儲存著各種各樣的資源
- 介面其實就是一個入口,你給我我要的引數,我給你你要的資料,怎麼給,並不神祕,程式碼實現而已
- 一臺電腦和另一臺電腦怎麼實現互動?網路,本文基於HTTP
- node是一門中間層後臺語言,而且特點個人感覺就是對庫的靈活使用
程式碼實現
話不多說,程式碼可得
- server1 簡單的解析請求,返回響應
let http = require('http');
let fs = require('fs');
let url = require('url');
let queryString = require('querystring');
let server = http.createServer((req,res)=>{
let {pathname,query} = url.parse(req.url,true);
console.log('有訪問',)
//字串模板
fs.readFile(`./www/${pathname}`,(err,data)=>{
if(err){
res.writeHead(404);
res.write('NOT Found');
res.end();
}else {
console.log(query.a)
res.write(data);
res.end();
}
複製程式碼
- server2 實現請求區分
- 此處一個小彩蛋,表單上傳成功返回亂碼時,需要設定響應頭'Content-Type':'text/html;charset=utf-8',下處程式碼即有呼叫
- 檔案上傳時,需要兩點
- 表單的enctype需要設定成"multipart/form-data"
- 當上傳的內容出現中文亂碼時,可以考慮檢視下檔案編碼是否為utf-8,若不是,必亂碼
let server = http.createServer((req,res)=>{
// console.log(1)
let pathName, getQuery , postQuery;
if(req.method=='GET'){
let {pathname, query} = url.parse(req.url,true);
pathName = pathname;
getQuery = query;
}else if(req.method == 'POST'){
let arr = [];
pathName = req.url;
//post請求會分批傳送,所以會觸發多次data事件
req.on('data',buffer=>{
arr.push(buffer);
})
req.on('end',()=>{
arr = Buffer.concat(arr);
console.log(arr.toString('utf-8'))
postQuery = arr.toString();
res.writeHead(200,{'Content-Type':'text/html;charset=utf-8'});
res.write('上傳成功');
res.end();
})
}
// console.log(pathName, getQuery , postQuery);
});
複製程式碼
- server3 實現表單檔案解析儲存
const http=require('http');
const util=require('buffer_util');
const fs=require('fs');
http.createServer((req, res)=>{
let boundary='--'+req.headers['content-type'].split('; ')[1].split('=')[1];
let arr=[];
req.on('data', buffer=>{
arr.push(buffer);
});
req.on('end', ()=>{
let buffer=Buffer.concat(arr);
//1.按照分隔符切分
let res=util.bufferSplit(buffer, boundary);
res.pop();
res.shift();
//2.每一個處理一下
res.forEach(buffer=>{
buffer=buffer.slice(2, buffer.length-2);
let n=buffer.indexOf('\r\n\r\n');
let info=buffer.slice(0, n).toString();
let data=buffer.slice(n+4);
if(info.indexOf('\r\n')!=-1){
//檔案
let res2=info.split('\r\n')[0].split('; ');
let name=res2[1].split('=')[1];
let filename=res2[2].split('=')[1];
name=name.substring(1, name.length-1);
filename=filename.substring(1, filename.length-1);
fs.writeFile(`upload/${filename}`, data, err=>{
if(err){
console.log(err);
}else{
console.log('上傳成功');
}
});
}else{
//普通訊息
let name=info.split('; ')[1].split('=')[1];
name=name.substring(1, name.length-1);
}
});
});
}).listen(8080);
複製程式碼