流浪的菜袅 2023-02-27 11:38 采纳率: 79.5%
浏览 35
已结题

去掉form表单传图片报错

大家好,小菜袅又来了
是这样的,我一开始上传图片,用form表单提交很顺利,但是这样的话,前端接收不到服务器响应,虽然在submit事件内加上xhr请求可以看到响应,但是这样的话,又会有两次请求。
因为要弄拖拽上传图片,这样的话不是用户触发input:file去选择文件,而且也不想用form表单去提交了,我就去掉form表单,直接btn事件内用xhr去发请求:

 <input type="file" name="avatar" id="">
    <div class="all"></div>
    <button id="btn">上传</button>
<script>
        /*
            drop 在可放置区域放置元素时触发
            dragover 当可拖动元素放置到可放置区域时触发
            dragstart 当可拖动元素开始拖动时触发
            dragenter 拖动的元素进入到可放置区域时触发
            dragleave 拖动的元素离开可放置区域时触发
            dragend 拖放过程结束
        */ 
       const container = document.querySelector('.all')
       const btn = document.querySelector('#btn')
       let file;
       container.addEventListener('dragenter',function(ev) {
            ev.preventDefault()
            ev.target.style.borderColor = 'red'
       })
       container.addEventListener('dragover',function(ev) {
        ev.preventDefault()
       })
       container.addEventListener('drop',function(ev) {
            console.log(111);
            ev.preventDefault()
            const items = Array.prototype.slice.call(ev.dataTransfer.items)
            console.log(items);
            items.forEach(val => {
                console.log(val);
                if(val.kind === 'file') {
                    // getAsFile就是将拖过来的图片,得到图片的file数据
                    file = val.getAsFile()
                    console.log('1111',file);
                    // console.log('file',ev.dataTransfer.files[0]);
                }
            })
       })
       btn.addEventListener('click',function(){
            let formdata = new FormData()
            formdata.append('avatar',file)
            const xml = new XMLHttpRequest()
            xml.open('post','http://localhost:3000/api/swiper',true)
            xml.setRequestHeader("Content-type", "multipart/form-data; boundary=---------------------------" + Date.now().toString(16));
            xml.onlonreadystatechangeoad = function(){
                if (xhr.readyState === 4 && xhr.status === 200) {
                    console.log(xhr.responseText);
                }
            }
            xml.send(formdata)
       })
    </script>

nodejs:

const express = require('express')
const router = express.Router()
const multer = require('multer')
const mysql = require('../model/orm')
let date = new Date()
const moment = require('moment')
let time = date.getTime()
let originalname;
let random = Math.floor(Math.random() * (1000 - 100 + 1)) + 100
let urlStr; 
let obj;
let arr = [];
let storage = multer.diskStorage({
    destination: function(req, file, cb) {
        cb(null, 'public/upload'); 
    },
    filename: function(req, file, cb) {
        originalname = Buffer.from(file.originalname, "latin1").toString("utf8");
        urlStr = time + '-' + random + '-' + originalname
        time = date.getTime()
        random = Math.floor(Math.random() * (10000 - 100 + 1)) + 100
        obj = {
            swi_url:'http://localhost:3000/upload/' + urlStr,
            swi_qiyong:'false',
            swi_type:"活动",
            swi_time:moment(new Date()).format()
        }
        arr.push(obj)
        cb(null, urlStr)
    }
})
let upload = multer({ storage: storage });
// upload.single('form'),
router.post('/',upload.single('avatar'),(req,res) => {
    try {
        console.log('files',req.files);
        console.log('body',req.body);
    } catch (err) {
        console.log(err);
        res.status(500).send(err);
    }
    // console.log(arr);
    // let swiper = mysql.model('swiper')
    // swiper.insert(arr,(err,data) => {
    //     if(err) {
    //         console.log(err);
    //         return 
    //     }
    //     res.send({
    //         code:200,
    //         msg:"post请求处理完毕"
    //     })
    // })
})
module.exports = router

这样子后,前端报500错误,服务器报:表单意外终结(Error: Unexpected end of form),为什么呀,求解答求解答求解答

  • 写回答

2条回答 默认 最新

  • BitGPT 2023-02-27 11:57
    关注

    该回答引用ChatGPT

    这个错误通常意味着表单格式不正确或丢失了某些必要的表单字段或标记。在你的代码中,我注意到你在发送 XMLHttpRequest 请求时设置了请求头部 Content-type 为 multipart/form-data,这是正确的设置,但是你使用了一个随机分隔符来生成表单边界标识符,这可能会导致表单格式不正确。

    相反,你可以使用 FormData 对象来构建表单数据,FormData 会自动为你生成边界标识符,你可以像这样修改你的前端代码:

    
    btn.addEventListener('click',function(){
      let formdata = new FormData();
      formdata.append('avatar',file);
      const xml = new XMLHttpRequest();
      xml.open('post','http://localhost:3000/api/swiper',true);
      xml.onlonreadystatechangeoad = function(){
          if (xhr.readyState === 4 && xhr.status === 200) {
              console.log(xhr.responseText);
          }
      };
      xml.send(formdata);
    });
    
    

    在你的后端代码中,你使用了 Multer 中间件来处理文件上传。注意,upload.single() 方法只会处理一个文件,并将其存储在 req.file 中。因此,你可以使用 req.file 来获取上传的文件,而不是使用 req.files。此外,如果出现错误,Multer 会将错误存储在 MulterError 对象中,你可以使用 instanceof 操作符来检查是否存在此类错误。在你的代码中,你可以像这样修改后端代码:

    
    router.post('/', upload.single('avatar'), (req, res) => {
      try {
        console.log('file', req.file);
        console.log('body', req.body);
      } catch (err) {
        if (err instanceof multer.MulterError) {
          console.log(err.code);
        } else {
          console.log(err);
        }
        res.status(500).send(err);
      }
    });
    
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 3月7日
  • 已采纳回答 2月27日
  • 创建了问题 2月27日

悬赏问题

  • ¥15 英飞凌TC387使用MCAL唤醒TJA1145问题
  • ¥15 android tv图标显示异常
  • ¥20 (标签-AR|关键词-预测分析)
  • ¥15 MATLAB矩阵分离问题
  • ¥15 QT IFW 自定义界面添加lineedit小键盘输入数字无效果
  • ¥15 python thinter动态建立Entry并读取数据
  • ¥150 电路仿真,演示反激变压器升压
  • ¥100 libcurl使用无法连接服务器问题
  • ¥30 链表栈表达式求值求解
  • ¥15 关于龙芯1b,JTAG停止调试服务