(jquery + eggjs)上传图片。后端读取写入图片正常,前端接收到收据之后就会刷新页面

服务端没有报错,只有前端在选择完图片后控制台输出的内容一闪而过。
百度了一番,基本上都是说button submit之类的,和我的情况不一样,我的html里只有一个input标签。
我把$.ajax换成axios上传也是相同的状况。

我发现后端只要注释掉这句 fs.writeFileSync(absFilePath, readStream); ,前端就能正常接收到内容,后端一写入文件,前端就会刷新。

我是在公司电脑上写的这个代码,我怀疑公司的网络是不是被作了什么设置才会这样的。
不知道有没有人遇到过相同的情况

追加补充:我发现我修改了后端的代码,前端的页面也会跟着刷新。按理来说egg-cli的热更新不是应该只针对后端代码的修改的吗。 我怀疑上面说的bug跟这个有点关系
HTML

<body>
    <input name="file" type="file" id="file"/>
  </body>

JS

$("#file").on("change", function (e){  
    let formData = new FormData();
    formData.append('files', e.target.files[0]);
    $.ajax({
    url: `http://127.0.0.1:7001/api/v1/posts`,
    type:"post",
    data: formData,
    contentType: false,
    processData: false,
    success:function (res){
      console.log(res);
    },
    error: function (e){
      console.log(e);
    }
})

})

后端代码config.default.js里的相关配置
//禁用安全校验

  config.security = {
      csrf: {
    enable: false
  }
};

//文件上传相关的配置

config.multipart = {
  mode: "file",
  fileSize: "100mb",
  fileExtensions: ['.zip','.jpg','.png']
};

//跨域相关的配置

config.cors = {
  origin: "http://127.0.0.1:5500",//允许哪个地址跨域
  allowMethods: "GET,POST,DELETE,PUT",//允许哪些方法跨域
  credentials: true//允许前端发送请求时携带cookie
};

后端代码 router.js

module.exports = app => {
  const { router, controller } = app;
  router.post("/api/v1/posts", controller.home.posts);//上传用户头像
};

后端代码 home.js

'use strict';

const Controller = require('egg').Controller;
const fs = require("fs");
const path = require("path");
class HomeController extends Controller {
  async posts(){
    const {ctx} = this;
    const file = ctx.request.files[0];
    console.log('file:', file);
    //生成存储文件的路径
    let filePath = path.join("/public/upload", file.filename);
    filePath = filePath.replace(/\\/g, "/");
    const absFilePath = path.join(this.config.baseDir, 'app', filePath);
    //写入文件
    const readStream = fs.readFileSync(file.filepath);
    fs.writeFileSync(absFilePath, readStream); 

    ctx.body = 111;
  }
}
module.exports = HomeController;
阅读 1.9k
2 个回答

总算知道是怎么回事了。我的目录结构是 upload-test > client文件夹 + server文件夹,我在vscode中将 upload-test文件夹添加作工作区。这样当我在client文件夹里的 index.html中右键 open with live server后,我修改了upload-test文件夹下的任何一个文件(包括server文件夹里的后端文件)都会刷新html文件。
当我们upload-test从工作区删除,分别将 cilent文件夹和server文件夹添加到工作区后,这时修改后端代码就不会刷新index.html了。 这时才上传文件就一切正常了,后端写入文件后,前端控制台也能正常显示结果而不再刷新了。

后端代码有报错, fs.writeFileSync(absFilePath, readStream); 这行代码运行前要保证文件的上级目录已存在。如果不存在,这个地方就会报错被egg框架捕获,由于报错导致后面没有 ctx.body = 111, 导致请求的http statusCode 是默认的 404, 所以前端在error回调的console.log 输出了错误。

可以在你的controller里捕获一下错误看看

async posts(){
    try {
        const {ctx} = this;
      const file = ctx.request.files[0];
      console.log('file:', file);
      //生成存储文件的路径
      let filePath = path.join("/public/upload", file.filename);
      filePath = filePath.replace(/\\/g, "/");
      const absFilePath = path.join(this.config.baseDir, 'app', filePath);
      //写入文件
      const readStream = fs.readFileSync(file.filepath);
      fs.writeFileSync(absFilePath, readStream); 

      ctx.body = 111;
    } catch(e) {
        console.log(e);
    }
  }
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题