如何在nextjs中发送文件而不是json?[副本]

6ju8rftf  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(100)

此问题已在此处有答案

Send file as response using NextJS API(4个答案)
13天前关闭

如何从route.ts或page.ts发送文件?文件可以位于文件系统中的任何位置。

我目前在后端的python + flask中使用此代码。

@app.route("/thumbnail/<string:filename>")
def get_file(filename):
    pathname = os.path.join(session['uploadpath'], filename)
    return send_file(pathname)

向浏览器发送图像-响应HTML+jinja代码.

<img src="/thumbnail/{{file}}" style="height:40px"/>

这使我能够从文件系统中的任何位置提供图像。
或者,我也可以在内存中创建一个图像,并将其作为文件发送,而无需保存它。

@app.route("/textimg")
def get_file(filename):
    img = Image.new('RGB',(120,40), color='red')
    fnt = ImageFont.truetype(app.root_path + '/FONTNAME.TTF', 36)
    d = ImageDraw.Draw(img)
    d.text((10,0), '123456', font=fnt, fill=(255,255,0))

    img_io = BytesIO()
    img.save(img_io, 'JPEG', quality=70)
    img_io.seek(0)
    
    return send_file(img_io, mimetype='image/jpeg')

现在,我需要迁移我的后端。客户希望我只使用nextjs,我找不到send_file的等价物。在nextjs中,我无法从public文件夹外部获取文件。
请帮助我解决这个问题-我如何在nextjs中发送_file?
我试过...

res.setHeader('Content-Type', 'image/jpg')
    const imageStream = createReadStream(file)
    pipeline(imageStream, res, (error) => {
        console.log(error);
    })

import fs from 'fs'
import path from 'path'

const filePath = path.resolve('.', 'images_folder/next.jpg')
const imageBuffer = fs.readFileSync(filePath)

export default function(req, res) {
  res.setHeader('Content-Type', 'image/jpg')
  res.send(imageBuffer)
}

import { ImageResponse } from "next/server";

export default async function get_file(req, res) {
  const filename = req.query.filename;
  const pathname = os.path.join(session['uploadpath'], filename);

  const imageResponse = new ImageResponse(pathname);
  imageResponse.headers.set("Content-Type", "image/png");

  return imageResponse;
}

谷歌搜索找到了这些代码片段但是

kjthegm6

kjthegm61#

不建议使用Next.js从服务器发送文件,因为Next.js是服务器端呈现的框架,文件应该使用公共文件夹静态提供。但是,如果你真的需要从服务器发送文件,你可以使用Express和Next.js来实现这一点。

in root directory create server.js file

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

const dev = process.env.NODE_ENV !== 'production'
const app = next({ dev })
const handle = app.getRequestHandler()

app.prepare().then(() => {
  const server = express()
  const upload = multer({ dest: 'uploads/' })

  server.post('/upload', upload.single('file'), (req, res) => {
    res.json({ file: req.file.filename })
  })

  server.get('/files/:filename', (req, res) => {
    const filename = req.params.filename
    res.sendFile(`${__dirname}/uploads/${filename}`)
  })

  server.all('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(3000, err => {
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })
})

在Next.js页面中执行以下操作

import React from 'react';
import axios from 'axios';

class MyPage extends React.Component {
  state = {
    file: '',
    uploadedFile: ''
  }

  handleFormSubmit = (event) => {
    event.preventDefault();
    const file = this.state.file;
    const formData = new FormData();
    formData.append('file', file);
    axios.post('/upload', formData)
      .then(response => {
        const uploadedFile = response.data.file;
        axios.get(`/files/${uploadedFile}`)
          .then(response => {
            const fileURL = response.data;
            this.setState({
              uploadedFile: fileURL
            })
          })
          .catch(error => console.log(error))
      })
      .catch(error => console.log(error))
  }

  render() {
    const { uploadedFile } = this.state;
    return (
      <>
        <h1>File Upload</h1>
        {uploadedFile && (
          <img src={uploadedFile} alt="uploaded-file" />
        )}
        <form onSubmit={this.handleFormSubmit}>
          <input type="file" onChange={(e) => this.setState({ file: e.target.files[0] })}/>
          <button type="submit">Upload</button>
        </form>
      </>
    )
  }
}

export default MyPage;

注意:这只是一个基本的例子,展示了如何从Next.js向服务器发送文件并将其作为响应返回。根据您的需要进行修改
在使用这种方法时,您需要了解一些事情,
1.处理错误:如果有相同的文件名在“上传”文件夹,该文件将被覆盖
1.这个方法只处理单个文件,如果你想要多个文件,你需要修改多个文件的配置。

相关问题