简体   繁体   English

如何在服务器上将图像保存为 URL?

[英]How can I save an image on the server as a URL?

EDIT编辑

I removed app.use(fileUpload());我删除app.use(fileUpload()); . . So it finally worked.所以它终于奏效了。 But unfortunately in the folder images of the backend I only get these files c43jnfeh734hdfudf .但不幸的是,在backend的文件夹images中,我只得到这些文件c43jnfeh734hdfudf

For this reason, nothing is displayed in the frontend.因此,前端不显示任何内容。

const imagePath = req.file.path
const description = req.file.originalname

console.log(imagePath)
console.log(description)
images\c43jnfeh734hdfudf
empty

I have a problem.我有个问题。 I would like to save images with a fixed URL on my server.我想在我的服务器上保存带有固定 URL 的图像。 I found the following code snippet, but unfortunately it doesn't work.我找到了以下代码片段,但不幸的是它不起作用。 I get the following error in the backend: 'TypeError: Cannot read property 'path' of undefined' .我在后端收到以下错误: 'TypeError: Cannot read property 'path' of undefined'

The following values are 'undefined' .以下值为'undefined' const imagePath = req.file.path const description = req.body.description How can I save an image as a URL on the server? const imagePath = req.file.path const description = req.body.description如何在服务器上将图像保存为 URL?

Here is the tutorial, where I found the code snippet https://github.com/meech-ward/sammeechward.com_mdx/blob/master/content/articles/uploading-images-express-and-react/index.mdx这是教程,我在其中找到了代码片段https://github.com/meech-ward/sammeechward.com_mdx/blob/master/content/articles/uploading-images-express-and-react/index.mdx

React反应

import { useState } from 'react'
import axios from 'axios'

export default function App() {
  const [file, setFile] = useState()
  const [description, setDescription] = useState("")
  const [image, setImage] = useState()

  const submit = async event => {
    event.preventDefault()

    const formData = new FormData()
    formData.append("image", file)
    formData.append("description", description)

    const result = await axios.post('/api/images', formData, { headers: {'Content-Type': 'multipart/form-data'}})
    setImage(result.data.imagePath)
  }

  return (
    <div className="App">
      <form onSubmit={submit}>
        <input
          filename={file} 
          onChange={e => setFile(e.target.files[0])} 
          type="file" 
          accept="image/*"
        ></input>
        <input
          onChange={e => setDescription(e.target.value)} 
          type="text"
        ></input>
        <button type="submit">Submit</button>
      </form>
      { image && <img src={image}/>}
    </div>
  )
}

Backend后端

const express = require('express')
const fs = require('fs')
const multer = require('multer')

const upload = multer({ dest: 'images/' })

const app = express()

// app.use('/images', express.static('images'))
app.get('/images/:imageName', (req, res) => {
  // do a bunch of if statements to make sure the user is 
  // authorized to view this image, then

  const imageName = req.params.imageName
  const readStream = fs.createReadStream(`images/${imageName}`)
  readStream.pipe(res)
})

app.post('/api/images', upload.single('image'), (req, res) => {
  const imagePath = req.file.path
  const description = req.body.description

  // Save this data to a database probably

  console.log(description, imagePath)
  res.send({description, imagePath})
})

app.listen(8080, () => console.log("listening on port 8080"))

routes/Test.js路线/Test.js

const express = require("express");
const router = express.Router();
module.exports = router;
const auth_util = require("../utilities/auth_util");
const pgclient = require("../app");
const multer = require('multer')
const upload = multer({ dest: 'images/' })

// app.use('/images', express.static('images'))
router.get('/images/:imageName', (req, res) => {
  // do a bunch of if statements to make sure the user is 
  // authorized to view this image, then

  const imageName = req.params.imageName
  const readStream = fs.createReadStream(`images/${imageName}`)
  readStream.pipe(res)
})

router.post('/api/images', upload.single('image'), (req, res) => {
  console.log(req.file)
  console.log(req.files)
  const imagePath = req.file.path
  const description = req.body.description

  // Save this data to a database probably

  console.log(description, imagePath)
  res.send({ description, imagePath })
})

// added the lines below
const path = require("path");

router.use(express.static(path.join(__dirname, 'build')));

router.get('/', function (req, res) {
  res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.js应用程序.js

const express = require("express");
const cors = require("cors");
//const fileUpload = require("express-fileupload");
const session = require("express-session");
const { Pool } = require("pg");



const app = express();

app.use(express.json());
//app.use(fileUpload());
//------------------------------CORS settings------------------------------
var whitelist = [
    "http://localhost:3000",
    "http://localhost:3001",
];
var corsOptions = {
    credentials: true,
    exposedHeaders: ["set-cookie"],
    origin: function (origin, callback) {
        if (whitelist.indexOf(origin) !== -1 || !origin) {
            callback(null, true);
        } else {
            // callback(null, true)
            callback(new Error("Not allowed by CORS!!"));
        }
    },
};
app.options("*", cors(corsOptions));

const pgclient = new Pool({
    user: process.env.DB_USER,
    host: process.env.DB_HOST,
    database: process.env.DB_DATABASE,
    password: process.env.DB_PASSWORD,
    port: process.env.DB_PORT,
});

module.exports = pgclient;


app.set("trust proxy", 1);


const testRoute = require("./routes/test");
app.use("/test", cors(corsOptions), testRoute);

app.get("/", cors(corsOptions), (req, res, next) => {
    res.send("Welcome");
});

module.exports = app;

First of all, you need to remove express-fileupload .首先,您需要删除express-fileupload There is no need to use it alongside multer .无需将它与multer一起使用。

To have the correct file with an extension in specified folder, you need to change this part of your code:要在指定文件夹中拥有带扩展名的正确文件,您需要更改这部分代码:

remove this line:删除此行:

const upload = multer({ dest: 'images/' })

change it to:将其更改为:

// routes/Test.js

const storage = multer.diskStorage({
  destination: function (req, file, cb) {
    cb(null, 'images')
  },
  filename: function (req, file, cb) {
    cb(null, file.originalname)
  }
})

const upload = multer({ storage: storage })

For conventional and standard way to prevent overwriting the same file names, you need to change filename to this:对于防止覆盖相同文件名的常规和标准方法,您需要将filename名更改为:

filename: function (req, file, cb) {
    cb(null, `${Date.now()}-${file.originalname}`)
}

According to this answer, multer uses a kind of cookie in its file uploads and out of date versions of the cookie cause the file upload to fail.根据这个答案,multer 在其文件上传中使用了一种 cookie,而 cookie 的过时版本会导致文件上传失败。 Try clearing your browser's cookies.尝试清除浏览器的 cookies。

multer - req.file always undefined multer - req.file 始终未定义

Edit: here is the script working on my end with some images:编辑:这是在我这边用一些图片工作的脚本: 在此处输入图像描述

I did have to make one minor edit to get the example to work on chrome.我确实需要做一个小的编辑才能让这个例子在 chrome 上运行。 To avoid the CORS policy, the front and back end must both be hosted at the same port.为了避免 CORS 策略,前端和后端必须都托管在同一个端口。 So, I added get route to statically serve the react page from the expressjs server:因此,我添加了获取路由以从 expressjs 服务器静态提供反应页面:

const express = require('express')
const fs = require('fs')
const multer = require('multer')

const upload = multer({ dest: 'images/' })

const app = express()

// app.use('/images', express.static('images'))
app.get('/images/:imageName', (req, res) => {
    // do a bunch of if statements to make sure the user is 
    // authorized to view this image, then

    const imageName = req.params.imageName
    const readStream = fs.createReadStream(`images/${imageName}`)
    readStream.pipe(res)
})

app.post('/api/images', upload.single('image'), (req, res) => {
    console.log(req.file)
    console.log(req.files)
    const imagePath = req.file.path
    const description = req.body.description

    // Save this data to a database probably

    console.log(description, imagePath)
    res.send({ description, imagePath })
})

// added the lines below
const path = require("path");

app.use(express.static(path.join(__dirname, 'build')));

app.get('/', function (req, res) {
    res.sendFile(path.join(__dirname, 'build', 'index.html'));
});

app.listen(8080, () => console.log("listening on port 8080"))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM