MongoDB
 sql >> Cơ Sở Dữ Liệu >  >> NoSQL >> MongoDB

Hình ảnh trả về từ API REST luôn hiển thị bị hỏng

Tránh gửi lại hình ảnh được mã hóa base64 (nhiều hình ảnh + tệp lớn + chuỗi mã hóa lớn =hiệu suất rất chậm). Tôi thực sự khuyên bạn nên tạo một microservice chỉ xử lý tải lên hình ảnh và bất kỳ yêu cầu get / post / put / delete liên quan đến hình ảnh nào khác. Tách nó khỏi ứng dụng chính của bạn.

Ví dụ:

  • Tôi sử dụng multer để tạo bộ đệm hình ảnh
  • Sau đó, sử dụng sharp hoặc fs để lưu hình ảnh (tùy thuộc vào loại tệp)
  • Sau đó, tôi gửi đường dẫn tệp đến bộ điều khiển để được lưu vào DB của tôi
  • Sau đó, giao diện người dùng thực hiện yêu cầu GET khi nó cố gắng truy cập:http://localhost:4000/uploads/timestamp-randomstring-originalname.fileext

Nói một cách dễ hiểu, microservice của tôi hoạt động giống như một CDN chỉ dành cho hình ảnh.

Ví dụ:người dùng gửi yêu cầu đăng bài tới http://localhost:4000/api/avatar/create với một số FormData:

Đầu tiên nó đi qua một số phần mềm trung gian Express:

libs / middlewares.js

...
app.use(cors({credentials: true, origin: "http://localhost:3000" })) // allows receiving of cookies from front-end

app.use(morgan(`tiny`)); // logging framework

app.use(multer({
        limits: {
            fileSize: 10240000,
            files: 1,
            fields: 1
        },
        fileFilter: (req, file, next) => {
            if (!/\.(jpe?g|png|gif|bmp)$/i.test(file.originalname)) {
                req.err = `That file extension is not accepted!`
                next(null, false)
            }
            next(null, true);
        }
    }).single(`file`))

app.use(bodyParser.json()); // parses header requests (req.body)

app.use(bodyParser.urlencoded({ limit: `10mb`, extended: true })); // allows objects and arrays to be URL-encoded

...etc     

Sau đó, truy cập avatars tuyến đường:

route / avatars.js

app.post(`/api/avatar/create`, requireAuth, saveImage, create);

Sau đó, nó chuyển qua một số xác thực người dùng, sau đó đi qua saveImage của tôi phần mềm trung gian:

services / saveImage.js

const createRandomString = require('../shared/helpers');
const fs = require("fs");
const sharp = require("sharp");
const randomString = createRandomString();

if (req.err || !req.file) {
  return res.status(500).json({ err: req.err || `Unable to locate the requested file to be saved` })
  next();
}

const filename = `${Date.now()}-${randomString}-${req.file.originalname}`;
const filepath = `uploads/${filename}`;

const setFilePath = () => { req.file.path = filepath; return next();}

(/\.(gif|bmp)$/i.test(req.file.originalname))
    ? fs.writeFile(filepath, req.file.buffer, (err) => {
            if (err) { 
              return res.status(500).json({ err: `There was a problem saving the image.`}); 
              next();
            }

            setFilePath();
        })
    : sharp(req.file.buffer).resize(256, 256).max().withoutEnlargement().toFile(filepath).then(() => setFilePath())

Nếu tệp được lưu, tệp sẽ gửi req.file.path vào create của tôi bộ điều khiển. Điều này được lưu vào DB của tôi dưới dạng đường dẫn tệp và đường dẫn hình ảnh (avatarFilePath hoặc /uploads/imagefile.ext được lưu cho mục đích xóa và avatarURL hoặc [http://localhost:4000]/uploads/imagefile.ext được lưu và sử dụng cho yêu cầu GET của giao diện người dùng):

controller / avatar.js (Tôi đang sử dụng Postgres, nhưng bạn có thể thay thế cho Mongo)

create: async (req, res, done) => {
            try {
                const avatarurl = `${apiURL}/${req.file.path}`;

                await db.result("INSERT INTO avatars(userid, avatarURL, avatarFilePath) VALUES ($1, $2, $3)", [req.session.id, avatarurl, req.file.path]);

                res.status(201).json({ avatarurl });
            } catch (err) { return res.status(500).json({ err: err.toString() }); done(); 
        }

Sau đó, khi giao diện người dùng cố gắng truy cập vào uploads thư mục qua <img src={avatarURL} alt="image" /> hoặc <img src="[http://localhost:4000]/uploads/imagefile.ext" alt="image" /> , nó được phục vụ bởi microservice:

libs / server.js

const express = require("express");
const path = app.get("path");
const PORT = 4000;

//============================================================//
// EXPRESS SERVE AVATAR IMAGES
//============================================================//
app.use(`/uploads`, express.static(`uploads`));

//============================================================//
/* CREATE EXPRESS SERVER */
//============================================================//
app.listen(PORT);

Nó trông như thế nào khi yêu cầu ghi nhật ký:

19:17:54 INSERT INTO avatars(userid, avatarURL, avatarFilePath) VALUES ('08861626-b6d0-11e8-9047-672b670fe126', 'http://localhost:4000/uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png', 'uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png')

POST /api/avatar/create 201 109 - 61.614 ms

GET /uploads/1536891474536-k9c7OdimjEWYXbjTIs9J4S3lh2ldrzV8-android.png 200 3027 - 3.877 ms

Những gì người dùng nhìn thấy khi yêu cầu GET thành công:




  1. Redis
  2.   
  3. MongoDB
  4.   
  5. Memcached
  6.   
  7. HBase
  8.   
  9. CouchDB
  1. Mongoose:CastError:Truyền tới ObjectId không thành công cho giá trị [đối tượng Đối tượng] tại đường dẫn _id

  2. mongoDB upert trên mảng

  3. Giá trị khác biệt đếm MongoDB?

  4. Redis và MongoDB:Những điều bạn cần biết

  5. MongoDB Object.bsonSize ()