最近使用vue做了个项目,把本地指定url下的png图片上传。
废话不多说,直接上代码:
var fs = require('fs') //需要引入nodejs中的文件操作部分
var http = require('http') //需要引入nodejs中http请求部分
/**
* 实际封装接口的入口
* @param {*} options 请求的配置项
* @param {*} path 文件上传路径
* @param {*} id 文件上传参数(id)
* @param {*} name 文件上传参数(name)
* @param {*} token 接口上传使用的token
* @param {*} cb 上传成功后的回调函数
* @param {*} errCb 上传失败后的回调
*/
function uploadFile(options, path, id, name, token, cb, errCb){
var req = http.request(options, (res)=>{
// console.log("RES:" + res);
// console.log('STATUS: ' + res.statusCode);
// console.log('HEADERS: ' + JSON.stringify(res.headers));
res.on("data", (chunk)=>{
console.log("BODY:" + chunk);
if(typeof cb == 'function'){ //如果请求成功返回,执行成功回调函数
cb(JSON.parse(chunk.toString())); //将结果返回,返回结果是json格式的情况下JSON.parse解析下再返回
}
})
})
req.on('error', (e)=>{
if(typeof errCb == 'function'){ //如果请求失败后,执行失败回调函数
errCb(e.toString()); //将结果返回
}
})
postFile([{urlKey: "file", urlValue: path}], req, id, name, token);
}
function postFile(fileKeyValue, req, id, name, token) {
var boundaryKey = Math.random().toString(16);
var enddata = '\r\n----' + boundaryKey + '--';
var files = new Array();
for (var i = 0; i < fileKeyValue.length; i++) {
var content = ''; // "\r\n----" + boundaryKey + "\r\n" + "Content-Type: image/jpeg\r\n" + "Content-Disposition: form-data; name=\"" + fileKeyValue[i].urlKey + "\"; filename=\"" + (fileKeyValue[i].urlValue) + "\"\r\n" + "Content-Transfer-Encoding: binary\r\n\r\n";
var contentBinary = new Buffer.from(content, 'utf-8');//当编码为ascii时,中文会乱码。
files.push({contentBinary: contentBinary, filePath: fileKeyValue[i].urlValue});
}
var contentLength = 0;
for (var i = 0; i < files.length; i++) {
var stat = fs.statSync(files[i].filePath);
contentLength += files[i].contentBinary.length;
contentLength += stat.size;
}
//请求参数放到了header头中,后台从header中取
req.setHeader('token', token);
req.setHeader('id', id);
req.setHeader('name', name);
// req.setHeader('Content-Type', 'multipart/form-data; boundary=--' + boundaryKey);//这里暂时不设置,浏览器会根据实际上传文件自动识别,如果不行再设置
req.setHeader('Content-Type', 'text/html; charset=UTF-8');
req.setHeader('Content-Length', contentLength + Buffer.byteLength(enddata));
// 将参数发出
var fileindex = 0;
var doOneFile = function(){
req.write(files[fileindex].contentBinary);
var fileStream = fs.createReadStream(files[fileindex].filePath, {bufferSize : 4 * 1024});
fileStream.pipe(req, {end: false});
fileStream.on('end', function() {
fileindex++;
if(fileindex == files.length){
req.end(enddata);
} else {
doOneFile();
}
});
};
if(fileindex == files.length){
req.end(enddata);
} else {
doOneFile();
}
}
函数的调用如下:
let options = {
host: that.$servletUri, //例如:127.0.0.1 不需加http://...
port: that.$servletPort, //例如:8080
method: "POST",
path: '/api/fileupload', //流上传方法名
}
let fileName = Date.parse(new Date());
// 该封装方法放入了utils工具类中,所以这里用this.$util.
this.$util.uploadFile(options, fileUrl, that.currentRowId, fileName,
this.$store.state.userInfo.token,(res)=>{
// 上传成功后执行的方法
if(res.code == 1){
this.$message('截图上传成功!')
}
},(err)=>{
this.$message.error('截图上传失败,请稍后重试!');
});
再贴一下后台代码:
controller:
@PostMapping("/fileupload")
public Response uploadFile(HttpServletRequest request, HttpServletResponse response,Integer id,String fileName) throws Exception{
//String fileName = "hh.png";//request.getParameter("fileName");
return documentService.uploadFile(request);
}
service:
Response uploadFile(HttpServletRequest request);
serviceImpl:
//
// 下面fileUpload这里对应yml文件中配置服务器保存的路径
//
// file:
// fileUpload: /home/work/java/images/
//
@Value("${file.fileUpload}")
private String fileUpload;
@Override
public Response uploadFile(HttpServletRequest request) {
Integer id = 0;
if (null != request.getHeader("id")){
id = Integer.parseInt(request.getHeader("id"));
}
String fileName1 =request.getHeader("name")+".png";
String dirPath =fileUpload+id;//会在webapp下面创建此文件夹
String fileFullPath = dirPath+System.getProperty("file.separator")+ fileName1;
InputStream input = null;
FileOutputStream fos = null;
try {
input = request.getInputStream();
File file = new File(dirPath);
if(!file.exists()){
file.mkdirs();
}
fos = new FileOutputStream(fileFullPath);
byte[] buffer = new byte[1024];
/* int size = 0;
byte[] buffer = new byte[4*1024];
while ((size = input.read(buffer,0,4*1024)) != -1) {
fos.write(buffer, 0, size);
}*/
int length = 0;
do {
length = input.read(buffer);
if (length > 0) {
fos.write(buffer, 0, length);
}
} while (length>0);
} catch (IOException e) {
e.printStackTrace();
return Response.successErr("操作失败");
} finally{
if(input != null){
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if(fos != null){
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}