当前位置: 首页 > 知识库问答 >
问题:

javascript - 关于前后端文件传输问题?

赵英资
2023-08-11

问题描述

我想将前端获取到的文件通过POST请求作为请求体参数传给后端,但是传过去之后发现文件是个空对象{}

问题出现的环境背景及自己尝试过哪些方法

问过chatgpt和查阅的一些资料后我尝试将File对象转化为Blob对象然后再传给后端,结果发现还是空对象{};之后我又尝试通过FormData来作为POST请求体参数可还是无济于事

相关代码

const videoInfo = reactive<videoInfo>({  videoFile: useVideo().videoFile,  videoCover: useVideo().videoCover,  title: "",  type: "",  tag: [],  description: "",})function uploadVideo(){  videoInfo.videoFile = fileToBlob(videoInfo.videoFile)  videoInfo.videoCover = fileToBlob(videoInfo.videoCover)  console.log(videoInfo.videoFile)  upload(videoInfo)  // videoInfo.videoFile = new FormData()  // videoInfo.videoCover = new FormData()  // videoInfo.videoFile.append("file",fileToBlob(useVideo().videoFile))  // videoInfo.videoCover.append("cover",fileToBlob(useVideo().videoCover))  // console.log(videoInfo.videoFile.get("file"))  // upload(videoInfo)}
export const upload = function(videoInfo){    return service({        url: "/uploadVideo",        method: "POST",        data:{            videoFile: videoInfo.videoFile,            videoCover: videoInfo.videoCover,            title: videoInfo.title,            type: videoInfo.type,            tag: videoInfo.tag.join(","),            description: videoInfo.description        },        headers:{            isToken: true        }    })}

以下是nodejs后端对路由的统一处理:

import express from "express"import bodyParser from "body-parser";import expressSession from "express-session"import redis from "redis"import config from "./config/config.js"import MyError from "./exception/index.js";import http from "http";import {FORBIDDEN_ERROR_CODE, NO_AUTH_ERROR_CODE} from "./exception/errorCode.js"import morgan from "morgan"import db from "./db.js"import redisClient from "./redis.js";import {getToken} from "./utils/token.js";// import RedisStore from "connect-redis"// const RedisStore = require("connect-redis")(expressSession);//连接redisredisClient.on("connect", function () {    console.log("Redis client connected");});redisClient.on("error", function (e) {    console.error(e);});// 请求大小限制const requestLimit = "5120kb";class ExpressServer {    constructor() {        this.app = express();        // 上下文请求路径        this.contextPath = "/api";        // 请求日志        this.app.use(morgan("short"));        this.app.use(            bodyParser.urlencoded({ extended: false, limit: requestLimit })        );        this.app.use(bodyParser.json({ limit: requestLimit }));        this.app.set("x-powered-by", false);        this.app.all("*", (req, res, next) => {            // 开启跨域            res.setHeader("Access-Control-Allow-Credentials", "true");            const origin = req.get("Origin");            // 允许的地址 http://127.0.0.1:9000 这样的格式            if (origin) {                res.setHeader("Access-Control-Allow-Origin", origin);            }            // 允许跨域请求的方法            res.setHeader(                "Access-Control-Allow-Methods",                "POST, GET, OPTIONS, DELETE, PUT"            );            // 允许跨域请求 header 携带哪些东西            res.header(                "Access-Control-Allow-Headers",                "Origin, X-Requested-With, Content-Type, Accept, If-Modified-Since"            );            next();        });        // 设置Express的Session存储中间件(跟之前session设置方法一样,只加了store项为redis存储)        // const sessionOptions = {        //     // store session存储实例,默认为一个新的 MemoryStore 实例。        //     store: new RedisStore({ client: redisClient }), // 只需设置这个就可存储到redis        //     name: "session_id", // 默认connect.sid        //     secret: "yupi", // 设置签名秘钥  内容可以任意填写        //     resave: false, // 强制保存,如果session没有被修改也要重新保存,默认true(推荐false)        //     saveUninitialized: true, // 如果原先没有session那么就设置,否则不设置(推荐true)        //     rolling: true, // 每次请求更新有效时长        //     cookie: {        //         // domain: ".yuindex.com", // 需要共享 cookie 时再设置        //         // 全局设置 cookie,就是访问随便 api 就会设置 cookie,也可以在登录的路由下单独设置        //         maxAge: 1000 * 60 * 60 * 24 * 30, // 30 天后过期        //         httpOnly: true, // 是否允许客户端修改 cookie(默认 true 不能被修改)        //     },        // };        // this.app.use(expressSession(sessionOptions));        this.server = http.createServer(this.app);    }    setRoute(path, method, handlerFunction) {        const handler = async (req, res) => {            // IP 过滤            const requestClientIp = getClientIp(req);            if (!requestClientIp) {                return FORBIDDEN_ERROR_CODE;            }            const event = req.body;            let result;            try {                const startTime = new Date().getTime();                let params;                if (event.file) {                    let eventCopy = { ...event };                    eventCopy.file = undefined;                    params = JSON.stringify(eventCopy);                } else {                    params = JSON.stringify(event);                }                console.log(                    `req start path = ${req.path}, clientIp = ${requestClientIp}, params = ${params}`                );                if (req.headers.istoken){                    if (await getToken(req.headers.authorization)){                        const token = await getToken(req.headers.authorization)                        event.Authorization = parseInt(token)                        console.log(typeof event.Authorization)                    }else {                        throw MyError(NO_AUTH_ERROR_CODE,"无权限访问,请重新登录")                    }                }                result = await handlerFunction(event, req, res);                // 封装响应                result = {                    code: 200,                    data: result,                };                console.log(                    `req end path = ${                        req.path                    }, clientIp = ${requestClientIp}, params = ${params}, costTime = ${                        new Date().getTime() - startTime                    }`                );            } catch (e) {                // 全局异常处理                if (e instanceof MyError) {                    result = {                        code: e.code,                        message: e.message,                        data: null,                    };                } else {                    result = {                        code: 500,                        data: null,                        message: "server error",                    };                }                console.error(                    `req error path = ${                        req.path                    }, clientIp = ${requestClientIp}, params = ${JSON.stringify(event)}`,                    e                );            }            res.send(result);        };        if (method === "POST"){            this.app.post(this.contextPath + path, handler);        }        if (method === "GET"){            this.app.get(this.contextPath + path, handler);        }    }    listen(port) {        this.server.listen(port);        let url = `http://localhost:${port}`;        if (this.contextPath) {            url += this.contextPath;        }        console.log(`server start at ${url}, env = ${process.env.NODE_ENV}`);    }}/** * 获取真实客户端 ip * @param req * @returns {*|string} */function getClientIp(req) {    if (!req) {        return "";    }    return (        req.headers["x-forwarded-for"] ||        req.connection?.remoteAddress ||        req.socket?.remoteAddress ||        req.connection?.socket?.remoteAddress ||        req.ip    );}// module.exports.CloudBaseRunServer = ExpressServer;export default ExpressServer

共有2个答案

龙逸清
2023-08-11
function uploadVideo() {  const formData = new FormData();  formData.append('videoFile', useVideo().videoFile);  formData.append('videoCover', useVideo().videoCover);  formData.append('title', videoInfo.title);  formData.append('type', videoInfo.type);  formData.append('tag', videoInfo.tag.join(','));  formData.append('description', videoInfo.description);  return service({    url: '/uploadVideo',    method: 'POST',    data: formData,    headers: {      isToken: true,      'Content-Type': 'multipart/form-data', // 这里要设置Content-Type为multipart/form-data    },  });}
丁正阳
2023-08-11
export const fileUpload = (params: any): Promise<any> => {  return request({    headers: {      'Content-Type': 'multipart/form-data',    },    method: 'post',    url: '/api-edu-polymeric/file/upload',    data: params  });};
 类似资料:
  • 在放开最后一行注释后执行 : A的引用内存反而降低了,A对B的引用好像并没有解除,为什么会降低内存了? 为什么A对象的内存降低了呢

  • springboot接收前端上传到后端的文件时,在controller层内大多数使用的是MultipartFile进行接收的,当使用file进行接收时会报错 有大佬知道为啥不能用file接收文件吗?

  • 我正在寻找以下问题的答案。 > 在服务器断开的情况下,Camel SFPT是否支持resume功能。我注意到,一旦从基础JSCH库抛出SocketTimeout/IOException异常,就会删除.inprogress文件。我的期望是,一旦连接可用,camel应该重新建立连接,并从它离开的地方恢复下载。 connectTimeout、timeout和soTimeout等参数不起作用。在windo

  • 前端上传文件一直报错,后端显示读文件出问题,刚进函数在绑定参数的时候就出了问题返回了 明明都能打印出来但文件就是上传不上去,服务器会报错 400 {"msg": "multipart: NextPart: EOF", "code": 40日, "data": null} 400 {"msg": "multipart: NextPart: EOF","code": 400, "data": null

  • 假设我有三个前端项目,是不是他们都走一个后端服务9090去同一个页面登录和接口获取token,这样就算单点登录?然后他们之后其他雪球再各自请求自己后端服务完成需求比如9091 9092 9093。 以java为例,我需要创建sso模块/9091模块 9092模块 9093模块这样吗 可以用redis解决

  • 本文向大家介绍浅谈Django前端后端值传递问题,包括了浅谈Django前端后端值传递问题的使用技巧和注意事项,需要的朋友参考一下 前端后端传值问题总结 前端传给后端 通过表单传值 1、通过表单get请求传值 在前端当通过get的方式传值时,表单中的标签的name值将会被当做action的地址的参数 此时,在后端可以通过get请求相应的name值拿到对应的value值 例子: html中: 视图中