关于ajax请求404 not found(koa处理请求)

题目描述

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

阅读 5.2k
1 个回答

首先通过控制面板查看它返回什么

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题