寫在前面
本篇介紹了前端提交數據給node的幾種處理方式,從最基本的get和post請求,到圖片上傳,再到分塊上傳,由淺入深。
GET請求
經典的get提交數據,參數通過URL傳遞給node,node通過url包和querystring將參數解析出來,這個很簡單,看代碼就可以了。
前端:
GET: <form action="http://localhost:8899/uploadGet" method="get"> <input type="text" placeholder="please enter name" name="name"> <input type="text" placeholder="please enter age" name="age"> <button>提交</button> </form>
node:
const http = require('http'); const url = require('url'); const querystring = require('querystring'); const fs = require('fs'); //這些引用后面代碼就不重復寫了 const app = http.createServer((req, res) => { let parsed_url = url.parse(req.url); if (parsed_url.pathname === '/uploadGet') { //匹配路由 let query = parsed_url.query; //獲取url的query:id=xx&name=xx let queryObj = querystring.parse(query); //將query字符串轉換成對象:{id:xx, name:xx} res.writeHead(201, { 'content-type': 'text/html' }) res.end(`<h2>${JSON.stringify(queryObj)}</h2>`); } }) app.listen(8899, () => { console.log('listen on 8899') })
POST請求
POST請求不是通過地址傳參,而是將參數添加到請求體中發起請求。所以此時node不能通過地址獲取參數,需要在req的on函數中獲取數據。
前端:
<form action="http://localhost:8899/uploadPost" method="post" name="lzxform"> <input type="text" placeholder="please enter name" name="name"> <input type="text" placeholder="please enter age" name="age"> <br><br /> <input type="file" name="lzxfile" id="upload"> <button>提交</button> <!-- <button onclick="submits(event)">提交</button> --> </form>
node:
if (parsed_url.pathname === '/uploadPost') { // 定義了一個post變量,用於暫存請求體的信息 var postData = ''; req.on('data', chunk => { //在on函數中獲取請求體 postData += chunk; //請求數據過大時會自動進行多次請求 }) req.on('end', () => { //請求結束 res.writeHead(201, { 'content-type': 'text/plain' }); res.end(postData); }) }
enctype
form標簽有一個屬性叫enctype,作用是規定在發送表單數據之前如何對其進行編碼,默認值是 application/x-www-form-urlencoded,上述代碼沒有指定該值,所以在請求體中,數據還是以鍵值對的方式發送:
但是這種鍵值對的模式不適合發送圖片這種二進制數據到后端,所以enctype還有個屬性是multipart/form-data,數據以如下形式進行發送:
node如何處理圖片數據
服務端拿到字符串或者數字可以直接保存到數據庫里去,但是拿到圖片或者文件這種二進制數據時就要特殊處理下了,需要先拿到上圖中藍框里的文件數據,再將數據保存到新的文件中。原生的node處理不是很方便,所以這里用了express來處理。
const express = require('express'); const multer = require('multer'); const upload = multer({ dest: './uploadedFiles' }); //設置圖片的保存路徑 const path = require('path'); const fs = require('fs'); var app = express() app.post('/uploadPost', upload.single('lzxfile'), function (req, res, next) { //lzxfile為上傳input的name if (req.file) { var ext = path.parse(req.file.originalname).ext; //獲取上傳的文件名后綴 fs.rename(req.file.path, req.file.path + ext, (err, data) => { //因為express另存為的文件默認沒有后綴,所以需要加下 if (err) { console.log(err); } else { console.log('rename done'); } }) } res.send(req.body) }) app.listen(8899)
這樣前端上傳的文件就會被保存到設置的 uploadedFiles 目錄下了。
前端提交blob數據給node
上文中我們用form來提交文件數據給node,form的缺點是上傳后的回調函數不是很方便,需要借助formData這個api才能實現,而且傳文件只能一次性直接上傳,不能對文件進行分割等處理。所以這時就需要前端獲取文件的blob數據再發送給后端
先來介紹下blob:
簡而言之就是我們可以通過blob來處理圖片或文本等二進制數據。關於blob的詳細介紹可以看:https://www.cnblogs.com/hhhyaaon/p/5928152.html
現在我們希望在ajax中獲取圖片數據,再發送給后端。