在sails.js中上载后图像不会立即显示

在sails.js中上载后图像不会立即显示,sails.js,Sails.js,在我的应用程序中,我已将上载的图像存储到文件夹./assets/uploads。我正在使用easyimage和imagemagick存储图像 在我的应用程序中,上传图像后,应该会显示新上传的图像。但即使页面刷新,也不会显示。但当我扬帆时,图像显示出来了 上传图像后如何立即显示图像?非常感谢 这是完全正常的情况,因为Sails处理资产的方式 问题是,sails lift时,资产将从/assets文件夹复制(包括目录结构和符号链接)到/.tmp/public,该文件夹将公开访问 因此,为了在上传后立

在我的应用程序中,我已将上载的图像存储到文件夹./assets/uploads。我正在使用easyimage和imagemagick存储图像

在我的应用程序中,上传图像后,应该会显示新上传的图像。但即使页面刷新,也不会显示。但当我扬帆时,图像显示出来了


上传图像后如何立即显示图像?非常感谢

这是完全正常的情况,因为Sails处理资产的方式

问题是,
sails lift
时,资产将从
/assets
文件夹复制(包括目录结构和符号链接)到
/.tmp/public
,该文件夹将公开访问

因此,为了在上传后立即显示图像,您基本上不需要将图像上传到
/assets/uploads
,而是上传到
/.tmp/public/uploads


现在唯一的问题是,每次应用程序重新启动时,
/.tmp
文件夹都会被重写,而将上载存储在
/tmp/…
中会使它们在每次
升空后被擦除。这里的解决方案是将上传存储在,例如,
/uploads
中,并有一个符号链接
/assets/uploads
,指向
。/uploads
。Sails使用
grunt
处理资产同步。默认情况下,
grunt watch
任务会忽略空文件夹,但只要文件夹中至少有一个文件,它就会始终同步它。因此,如果您打算使用默认的静态中间件为上传的文件提供服务器,那么这里最快的解决方案就是确保在执行
sails lift
操作时,
assets/uploads
文件夹中至少有一个文件。在这种情况下,
uploads
文件夹将始终同步到您的
.tmp/public
文件夹,随后上载到该文件夹的任何内容都将自动复制并立即可用


当然,这会导致每次您的电梯起航时,您上传的所有文件都被复制到
.tmp/public
,这可能是您不想要的。要解决这个问题,您可以使用他在回答中发布的符号链接技巧@bredikhin。

虽然这个问题很老,但我想添加一个我刚刚实现的解决方案

今天我花了将近4个小时尝试所有这些解决方案但没有任何帮助。我希望此解决方案可以节省其他人的时间

为什么上传到任何自定义目录后图像不能立即可用

因为根据默认的Sails设置,您不能直接从
资产
目录访问资产。相反,您必须访问
.tmp/public
目录下的现有资产,这些资产是在
起航时由
Grunt
带入的

问题

  • (可用但不稳定)如果您将文件(如图像)上载到
    .tmp/public
    目录下,您的文件(图像)将在下一次
    sails lift
  • (不可用)如果您在任何其他自定义目录中上载文件,例如:
    /assets/images
    ,上载的文件将不会立即可用,但在下一次
    sails lift
    时它将可用。这是没有意义的,因为-无法在每次生产中上载文件时重新启动服务器
  • 我的解决方案(假设我想在
    /assets/images
    目录中上载我的图像)

  • 上传文件,在
    /tmp/public/images/image.ext中说
    (可用且易失)

  • 上传完成后,将文件
    image.ext
    复制到
    /assets/images/*file.ext
    (未来证明)

  • 代码

    var uploadToDir = '../public/images'; 
    req.file("incoming_file").upload({
        saveAs:function(file, cb) {
            cb(null,uploadToDir+'/'+file.filename);
        }
    },function whenDone(err,files){
        if (err) return res.serverError(err);
        if( files.length > 0 ){
    
            var ImagesDirArr = __dirname.split('/'); // path to this controller
            ImagesDirArr.pop();
            ImagesDirArr.pop();
    
            var path = ImagesDirArr.join('/'); // path to root of the project
            var _src = files[0].fd             // path of the uploaded file  
    
            // the destination path
            var _dest = path+'/assets/images/'+files[0].filename 
    
            // not preferred but fastest way of copying file
            fs.createReadStream(_src).pipe(fs.createWriteStream(_dest));
            return res.json({msg:"File saved", data: files});
        }
    });
    
    我一点也不喜欢这个解决方案,但它节省了我更多的时间,并且在dev和prod-ENV中都能完美地工作

    谢谢

    尝试这样做:

    • npm安装grunt同步--保存开发--保存精确版本
    • 取消注释行:
      //grunt.loadNpmTasks('grunt-sync')
      通常它位于文件
      /tasks/config/sync.js
      的末尾
    • 再次提起应用程序

    回到

    我使用的是节点版本10.15.0,我遇到了同样的问题。我通过更新到node的当前版本(12.4.0)并更新npm和所有节点模块解决了这个问题。在此之后,我修复了漏洞(只需运行“npm audit fix”),并修复了将图像上载到assets/images文件夹时出现的grunt错误。

    尝试此实现

    创建一个帮助器以同步文件

    filesync助手的示例

    // import in file
    const fs = require('fs')
    
    module.exports = {
    
    
      friendlyName: 'Upload sync',
    
    
      description: '',
    
    
      inputs: {
        filename:{
          type:'string'
        }
      },
    
    
      exits: {
    
        success: {
          description: 'All done.',
        },
    
      },
    
    
      fn: async function ({
        filename
      }) {
        var uploadLocation = sails.config.custom.profilePicDirectory + filename;
        var tempLocation = sails.config.custom.tempProfilePicDirectory + filename;
    
        //Copy the file to the temp folder so that it becomes available immediately
        await fs.createReadStream(uploadLocation).pipe(fs.createWriteStream(tempLocation));
        // TODO
        return;
      }
    
    
    };
    
    
    
    现在调用此帮助程序将文件同步到.temp文件夹

    const fileName = result[0].fd.split("\\").reverse()[0];
    
    //Sync to the .temp folder
    await await sails.helpers.uploadSync(fileName);
    
    保存在环境中的引用

    
    profilePicDirectory:path.join(path.resolve(),"assets/images/uploads/profilePictures/")
    
    tempProfilePicDirectory:path.join(path.resolve(),".tmp/public/images/uploads/profilePictures/"),
    
    也可以试试

    process.cwd()+filepath
    

    请注意,您必须在符号链接中使用绝对路径才能工作。例如,将
    uploads
    文件夹放在项目的根目录中,并在
    assets
    中添加一个符号链接,指向
    uploads
    /path/to/app/uploads
    ,然后该符号链接将被复制到
    .tmp/public
    。很复杂,但它可以工作(前提是
    上传
    中有文件)。谢谢你的解决方案,它真的帮助了我。但我解决了将上传的文件保存到资产的问题,因此下次服务器被解除时,tmp将再次使用这些文件重写