题目描述
nodeJS的KOA框架中使用koa-router处理url路由时前端无法获得服务端返回值
题目来源及自己的思路
相关代码
// 请把代码文本粘贴到下方(请勿用图片代替代码)
前端JavaScript:
$.ajax({
type: 'POST',
url: "http://127.0.0.1:8081/uploadimgs",
data:formData,
dataType: "json", //声明成功使用json数据类型回调
//如果传递的是FormData数据类型,那么下来的三个参数是必须的,否则会报错
cache:false, //默认是true,但是一般不做缓存
processData:false, //用于对data参数进行序列化处理,这里必须false;如果是true,就会将FormData转换为String类型
contentType:false, //一些文件上传http协议的关系,如果上传的有文件,那么只能设置为false
success: function(msg){
console.log('msg: '+msg);
console.log('文件上传成功');
//在这里使用ajax向后端请求base64图片
//输出文件夹路径
var outputDir='C:/ajax/output/'+$port.toLowerCase();
console.log('outputDir: '+outputDir);
//向后端发送输出文件夹路径
$.ajax({
type: 'POST',
url:'http://127.0.0.1:8081/backImgs',
data:{
outdir:outputDir
},
dataType:"json",
//发送请求,请求图片数据
success:function(msg){
console.log('msg: '+msg);
subAndJump(msg);
},
error:function(err){
console.log('請求圖片數據失敗...');
console.log(err);
}
});
},
error:function(){
console.log('ajax请求失败!');
}
});
后端nodeJS app.js
router.post('/uploadimgs',async (ctx,next) => {
//初始化子进程退出标志
childProcessExit=false;
let form = new multiparty.Form({
uploadDir:'C:/ajax/input/',
keepExtensions:true,//保留后缀
autoFields:true,
autoFiles:true
});
//设置返回消息JSON
let errsign={status:500,exception:null};
let datasign={status:200,recordset:null};
//创建图片上传函数loadimg()包含逻辑判断
function loadimg() {
let send_json={};
return new Promise((resolve,reject)=>{
form.parse(ctx.req,function(err,fields,files){
if(err){
// throw err;
console.log(err);//Error: write after end
send_json={
exception:"解析失败",
err:false
};
resolve(send_json);
// return send_json;
}else{
//存储网盘名及端口名
controlMessage.port=fields.port;
controlMessage.nameCH=fields.name_ch;
controlMessage.nameEN=fields.name_en;
send_json={
recordset:"上传成功",
err:true}
resolve(send_json);
let workProcess=exec('python C:/ajax/main.py ' +controlMessage.nameCH+' '+controlMessage.nameEN+' '+controlMessage.port+' ',function(error,stdout,stderr){
if(stdout.length >1){
console.log('you offer args:'+stdout);
} else {
console.log('you don\'t offer args');
}
if(error) {
console.info('stderr : '+stderr);
}
});
workProcess.on('exit',(code)=>{
console.log('子进程已退出,退出码:'+code);
childProcessExit=true;//子进程退出标识设为true
console.log('childProcessExit: '+childProcessExit);
});
}
});
//监听文件上传
form.on('file',(name,file)=>{
// console.log('fileName='+file.fieldName);
// console.log('originalFilename='+file.originalFilename);
// console.log('path='+file.path);
fs.rename(file.path,'C:/ajax/input/'+file.originalFilename,(err)=>{
if(err){
throw err;
}
})
});
});
}
await loadimg().then(sendjson=>{
// console.log("sendjson = "+sendjson);
if(sendjson.err===false){
errsign["exception"]=sendjson.exception;
ctx.body=errsign;
}else{
datasign["recordset"]=sendjson.recordset;
ctx.body=datasign;
}
});
});
//下面用于接收post请求并返回切割完成的图片
router.post('/backImgs',async (ctx,next)=>{
console.log('返回图片开始');
var num=0;
//轮询
var timer=setInterval(async function(){
num++;
console.log('第'+num+'次轮询');
if(childProcessExit){
console.log(1);
clearInterval(timer);
await pictureTrans().then(picBase64=>{
ctx.body=picBase64;
});
}
//6s后清除定时器
if(num>6){
clearInterval(timer);
throw new Error('检测失败,子进程未运行...');
}
},1000);
function pictureTrans(){
return new Promise((resolve,reject)=>{
console.log('开始执行pictureTrans')
let dir=ctx.request.body.outdir;
console.log(`需要导出图片文件夹: ${dir}...`);
//解析需要遍历的文件夹
var filePath = path.resolve(dir);
//根据文件路径读取文件,返回文件列表
fs.readdir(filePath,function(err,files){
if(err){
console.warn(err)
}else{
//创建对象,用于返回图片base64字符串合集
var picBase64={};
//遍历读取到的文件列表
files.forEach(function(filename){
//获取当前文件的绝对路径
var filedir = path.join(filePath,filename);
//根据文件路径获取文件信息,返回一个fs.Stats对象
fs.stat(filedir,function(eror,stats){
if(eror){
console.warn('获取文件stats失败');
}else{
var isFile = stats.isFile();//是文件
var isDir = stats.isDirectory();//是文件夹
if(isFile){
console.log(`检测到图片文件: ${filedir}...`);
let data = fs.readFileSync(filedir);
data = new Buffer(data).toString('base64');
console.log('data: '+data);
console.log(`data数据类型: ${typeof data}`);
console.log('filename: '+filename);
picBase64[filename]=data;
console.log(`picBase64.${filename}: ${picBase64[filename]}`);
}
if(isDir){
fileDisplay(filedir);//递归,如果是文件夹,就继续遍历该文件夹下面的文件
}
}
})
});
//返回图片的base64编码对象
console.log('开始返回base64图片信息');
resolve(picBase64);
}
});
});
}
//console.log('dir:'+ctx.request.body.outdir);
//接收前端发送的导出图片路径,循环检测childProcessExit的值
//若值为true,则开始将文件夹下的图片转为base64格式并返回
});
app.use(router.routes());
app.listen(8081);
你期待的结果是什么?实际看到的错误信息又是什么?
我看到前端对后台的/uploadimgs访问成功,得到消息msg,而访问/backImags失败显示404
下面是控制台打印情况:
console:
network:
PS:app.js显示文件读取正常,也已经成功转为base64位编码
在线等,求大佬提供点解决思路OTZ