流浪的菜袅 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条回答 默认 最新

  • CodeBytes 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 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么
  • ¥15 banner广告展示设置多少时间不怎么会消耗用户价值
  • ¥16 mybatis的代理对象无法通过@Autowired装填
  • ¥15 可见光定位matlab仿真
  • ¥15 arduino 四自由度机械臂
  • ¥15 wordpress 产品图片 GIF 没法显示
  • ¥15 求三国群英传pl国战时间的修改方法
  • ¥15 matlab代码代写,需写出详细代码,代价私
  • ¥15 ROS系统搭建请教(跨境电商用途)
  • ¥15 AIC3204的示例代码有吗,想用AIC3204测量血氧,找不到相关的代码。