一. 框架
選用express框架,文件
npm init
npm install express --save
複製程式碼
二. 簡單測試請求
在當前目錄新建index.js檔案
const express = require("express");
const app = express();
app.get("/", (req, res) => {
res.send("Hello Node.js");
});
const port = 3000;
app.listen(port);
複製程式碼
在終端輸入:
node index.js
在瀏覽器中開啟127.0.0.1:3000
三.使用form上傳圖片
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>upload</title>
</head>
<body>
<form action="http://127.0.0.1:3000/upload" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="avatar" accept="image/*">
</div>
<input type="submit" value="上傳">
</form>
</body>
</html>
複製程式碼
將index.js中的介面更新成
app.post("/upload", (req, res) => {
res.send('上傳成功')
});
複製程式碼
注意:index.js中的檔案只要改了,就要重新啟動服務
試著上傳一下:
四. 將前端傳送的圖片儲存在伺服器中
這裡需要用到一個叫multer的庫
npm install multer --save
根據他的文件,改一下index.js:
const express = require("express");
const multer = require("multer");
// 這裡定義圖片儲存的路徑,是以當前檔案為基本目錄
const upload = multer({ dest: "uploads/" });
const app = express();
/*
upload.single('avatar') 接受以avatar命名的檔案,也就是input中的name屬性的值
avatar這個檔案的資訊可以衝req.file中獲取
*/
app.post("/upload", upload.single("avatar"), (req, res) => {
console.log(req.file);
res.send("上傳成功");
});
const port = 3000;
app.listen(port);
複製程式碼
改完之後重新啟動服務,再重新上傳:
可以看到req.file中就是上傳的檔案資訊。
同時,你會發現當前目錄下,會多一個資料夾叫uoloads。
那個很長名字的檔案,就是剛剛前端傳的圖片。只要改一下字尾名就可以預覽了:
五. 將儲存的圖片名返回給前端
一般上傳完頭像會有一個預覽功能,那麼只需要後端將上傳後的圖片名傳送給前端,前端重新請求一下圖片就好了,前面都是用form預設的提交,這個提交存在一個問題就是,提交完成後頁面會發生跳轉。所以現在一般都是用ajax進行上傳。
// js程式碼
upload.addEventListener('submit', (e) => {
// 阻止form 的預設行為
e.preventDefault();
// 建立FormData物件
var formData = new FormData();
var fileInput = document.querySelector('input[name="avatar"]');
formData.append(fileInput.name, fileInput.files[0]);
// 建立XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open('POST', upload.action);
xhr.onload = function() {
console.log(xhr.response)
}
xhr.send(formData);
})
複製程式碼
- 小提示:如果HTML的元素有id屬性,那麼可以不用
document.querySelector
去選中它,可以直接使用,就像全域性變數一樣。
// index.js
app.post("/upload", upload.single("avatar"), (req, res) => {
res.json({name: req.file.filename }); // 使用json格式返回資料。
});
複製程式碼
這時候重新傳送,會出現一個問題:
由於程式碼是寫在 JS Bin上的,使用AJAX請求不同域名的介面,會出現跨域情況,解決這個問題需要,在index.js中加上一個頭部,就是報錯資訊中的Access-Control-Allow-Origin
:
app.post("/upload", upload.single("avatar"), (req, res) => {
res.set('Access-Control-Allow-Origin', '*');
res.json({name: req.file.filename });
});
複製程式碼
*
表示所有其他域名都可訪問,也可以將*
改為其他允許的域名。
重新傳送:
這樣成功的上傳了圖片,並且拿到了上傳後的圖片名。
這裡可以使用一個庫cors,來完成新增響應頭的操作:
npm install cors --save
修改index.js
const express = require("express");
const multer = require("multer");
const cors = require('cors'); // 新增
// 這裡定義圖片儲存的路徑,是以當前檔案為基本目錄
const upload = multer({ dest: "uploads/" });
const app = express();
app.use(cors()); // 新增
/*
upload.single('avatar') 接受以avatar命名的檔案,也就是input中的name屬性的值
avatar這個檔案的資訊可以衝req.file中獲取
*/
app.post("/upload", upload.single("avatar"), (req, res) => {
res.json({name: req.file.filename });
});
const port = 3000;
app.listen(port);
複製程式碼
五. 展示上傳後的圖片
新定義一個介面:
app.get("/preview/:name", (req, res) => {
res.sendFile(`uploads/${req.params.name}`, {
root: __dirname,
headers:{
'Content-Type': 'image/jpeg',
},
}, (error)=>{
if(error){
res.status(404).send('Not found')
}
});
});
複製程式碼
/preview:name
這種方式定義介面的路徑,請求過來的時候,就可以從req.params.name中拿到/preview/xxxx
中的xxxx了。
修改下HTML:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>JS Bin</title>
</head>
<body>
<form id="upload" action="http://127.0.0.1:3000/upload" method="post" enctype="multipart/form-data">
<div>
<input type="file" name="avatar" accept="image/*">
</div>
<input type="submit" value="上傳">
</form>
<img src="" id="avatarImg"> <!-- 新增 -->
</body>
</html>
複製程式碼
改下js
upload.addEventListener('submit', (e) => {
// 阻止form 的預設行為
e.preventDefault();
// 建立FormData物件
var formData = new FormData();
var fileInput = document.querySelector('input[name="avatar"]');
formData.append(fileInput.name, fileInput.files[0]);
// 建立XMLHttpRequest
var xhr = new XMLHttpRequest();
xhr.open('POST', upload.action);
xhr.onload = function() {
var imgName = JSON.parse(xhr.response).name; // 新增
avatarImg.setAttribute('src', 'http://127.0.0.1:3000/preview/' + imgName); // 新增
}
xhr.send(formData);
})
複製程式碼
結果:
六. 將程式碼部署到Heroku
Heroku是一個支援多種程式語言的雲平臺即服務。最重要的它是免費的。這是他的官方網站Heroku,注意不科學上網的話,可會超級慢或者進不去。而且科學上網要全域性模式..
- 註冊,過程省略
- 選擇建立一個新的應用
-
在部署的時候,有三個選擇,我選擇選擇GitHub
-
由於選擇GitHub,那麼還需要建立一個倉庫,把程式碼放上去。
-
放上去之間還要改一下程式碼:
因為部署是交給heroku的,所以埠號不能寫死:
const port = process.env.PORT || 3000; 複製程式碼
-
在package.json新增一個npm start命令
"start": "node index.js"
-
在GitHub上建立倉庫並上傳程式碼,過程略,別忘了寫.gitignore檔案
-
這是我的倉庫地址
-
在heroku中選擇倉庫並且選擇分支master,部署
- 預覽
這個就是部署好的域名了。
用這個域名試一試
大功告成。可惜的就是heroku得科學上網才行。