【问题标题】:Streaming image data from node server results in corrupted file (gridfs-stream)从节点服务器流式传输图像数据会导致文件损坏 (gridfs-stream)
【发布时间】:2018-11-14 03:01:22
【问题描述】:

我决定在此处(123)和此处(12)和许多其他相关帖子进行广泛搜索后发布此内容。我正在失去希望,但不会轻易放弃:)

我正在使用 multer 将 PNG 图像上传到 mongo 数据库:

const storage = new GridFsStorage({
    url: 'mongodb://my_database:thisIsfake@hostName/my_database',
    file: (req, file) => {
      return new Promise((resolve, reject) => {
        crypto.randomBytes(16, (err, buf) => {     // generating unique names to avoid duplicates
          if (err) {
            return reject(err);
          }
          const filename = buf.toString('hex') + path.extname(file.originalname);
          const fileInfo = {
            filename: filename,
            bucketName: 'media',
            metadata : {
              clientId : req.body.client_id  // added metadata to have a reference to the client to whom the image belongs
            }
          };
          resolve(fileInfo);
        });
      });
    }
  });
const upload = multer({storage}).single('image');

然后我创建一个流并将其传递给响应:

loader: function (req, res) {
    var conn = mongoose.createConnection('mongodb://my_database:thisIsfake@hostName/my_database');
    conn.once('open', function () {
    var gfs = Grid(conn.db, mongoose.mongo);
    gfs.collection('media'); 
    gfs.files.find({ metadata : {clientId : req.body.id}}).toArray(
    (err, files) => {
        if (err) throw err;
        if (files) {
            const readStream = gfs.createReadStream(files[0].filename);  //testing only with the first file in the array
            console.log(readStream); 
            res.set('Content-Type', files[0].contentType)
            readStream.pipe(res);    
        }  
    });  
    });
}

Postman 对端点的 POST 请求导致响应正文显示为图像文件:

在前端,我将响应传递到一个 File 对象中,读取它并将结果保存在 img 的 src 属性中:

findAfile(){
            let Data = {
                id: this.$store.state.StorePatient._id,         
            };
            console.log(this.$store.state.StorePatient._id);
            visitAxios.post('http://localhost:3000/client/visits/findfile', Data )
            .then(res => {
                const reader =  new FileReader();
                let file = new File([res.data],"image.png", {type: "image/png"});
                console.log('this is file: ',file);
                reader.readAsDataURL(file);  // encode a string  
                reader.onload = function() {
                    const img = new Image();
                    img.src = reader.result;
                    document.getElementById('imgContainer').appendChild(img);
                };
            })
            .catch( err => console.error(err));

        }

我的 File 对象类似于我在使用更大的输入字段时得到的对象:

这是原始文件:

检查元素时,我看到:

看起来数据 URI 应该在哪里,但它与文件输入中的原始图像不同:

再次,当我想通过输入元素显示它时:

onFileSelected(event){
        this.file = event.target.files[0];
        this.fileName = event.target.files[0].name;
        const reader =  new FileReader();
        console.log(this.file);
        reader.onload = function() {
             const img = new Image();
             img.src = reader.result;
             document.getElementById('imageContainer').appendChild(img);
        };
        reader.readAsDataURL(this.file);   
}

我明白了:

但是从响应中读取它时,它已损坏:

Postman 没看错,所以我的前端代码肯定有问题,对吧?如何将此 gfs 流传递给我的 html?

【问题讨论】:

  • 我设法发出 POST 请求以首先将文件写入服务器:var wstream = fs.createWriteStream(path.join(__dirname,"uploads", "fileToGet.jpg")); readStream.pipe(wstream);

标签: node.js mongodb vue.js


【解决方案1】:

我设法发出 POST 请求以从 MongoDB 获取图像并将其保存在服务器目录中:

const readStream = gfs.createReadStream(files[0].filename);
const wstream = fs.createWriteStream(path.join(__dirname,"uploads", "fileToGet.jpg"));        
readStream.pipe(wstream);

然后,我只是做了一个简单的 GET 请求,添加了绝对路径,最后在成功响应后删除文件:

app.get('/image', function (req, res) {
  var file = path.join(dir, 'fileToGet.jpg');
  if (file.indexOf(dir + path.sep) !== 0) {
      return res.status(403).end('Forbidden');
  }
  var type = mime[path.extname(file).slice(1)] || 'text/plain';
  var s = fs.createReadStream(file);
  s.on('open', function () {
      res.set('Content-Type', type);
      s.pipe(res);
  });
  s.on('end', function () {
      fs.unlink(file, ()=>{
        console.log("file deleted");
      })
  });
  s.on('error', function () {
      res.set('Content-Type', 'text/plain');
      res.status(404).end('Not found');
  });

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-16
    • 1970-01-01
    • 2012-08-03
    • 1970-01-01
    • 2013-01-30
    • 1970-01-01
    相关资源
    最近更新 更多