异步文件上传

本文介绍了FormData对象用于模拟HTML表单,便于文件异步上传。详细讲述了FormData的创建、使用方法,包括添加、修改、删除数据以及检查数据是否存在。通过结合multer插件,演示了文件上传的前后端实现,并讨论了文件上传后的预览效果。同时,文章还探讨了同源策略的概念、目的以及同源策略对Ajax请求的影响,提到了CORS作为跨域解决方案。

初识formdata对象

这个对象就是在文件上传的时候,使用。

formData对象作用

  1. 模拟html表单,相当于将html表单映射成表单对象,自动将表单对象中的数据拼接成请求参数的格式

    准备HTML表单

    <form methods="post">
      <input type="file" id="img">
    </form>

    把HTML的表单数据转换成formdata数据

    var form = new FormData()

    提交数据,一般使用post请求发送数据即可,也可以使用ajax

  2. 异步上传二进制文件,后面我们会讲到文件上传

6.1.2 FormData对象的使用

formdata概念

创建formdata对象

数据存储形式

 首先,我们要明确FormData里面存储的数据形式,一对key/value组成一条数据,key是唯一的,一个key可能对应多个value。如果使用表单初始化FormData对象,每一个表单字段对应一条数据,他们的name属性值对应key值,value属性值对应value值。

这种形式就类似于本地存储中存储数据的格式。

6.1.3 FormData对象实例的方法

前面我们说了如何实例化FormData对象,接下来我们看一下FormData对象有哪些常见的方法呢?

  1. 获取数据的方法 formdata.get(key);

  2. 添加数据的方法 formdata.append(key,value)

  3. 设置/修改数据 formdata.set(key,value),如果key不存在新增一条数据,如果存在,则修改对应的value值。

  4. 删除数据,通过key值删除

  5. 判断是否存在某条数据 formdata.has(key),存在返回true,不存在返回false。

6.1.4 FormData文件上传

前面我们主要是说了formdata的基本使用,下面我们使用formdata做一个文件上传的功能。

要做文件上传我们可以使用multer插件,首先先在本地安装

cnpm i multer --save

文件上传主要分为前后端,我们使用Jquery版ajax的上传方式,前端先定义个html的简单的表单, input的类型是file类型给他设置一个id值。

$('#img').change(function(){
  // 获取文件上传的信息
  // console.log(this.files[0])
​
  // 文件上传必须要使用formData对象
  var formdata = new FormData();
  // 调用formdata中有个方法 append 追加的意思
​
  //把文件上传的信息添加到了formdata对象中,属性名是imgfile 属性值:当前文件信息
  // {imgfile:as;dja;sdj;asd}
  formdata.append('imgfile',this.files[0]);
​
​
  // 发送ajax
  $.ajax({
    // 访问users路由文件下的upload路由
    url:'/users/upload',
    type:'post',
    data:formdata,  //传递文件上传的对象
​
    // 一旦文件上传,必须要有这个两个属性。如果没有将会报错
​
    // 文件上传的时候,内存处理中是以二进制的方式去上传
    // 正常的是数据处理,在发生ajax的时候,一般都是把数据转换为字符串进行传递的。
    // processData该属性的值默认为true,就是以字符串的形式传递。false,不以字符串的形式传递
    processData:false,
​
    // 更改数据的类型,默认为true,改为为false就是不使用默认的形式
    contentType:false,
​
    success:function(res){
      // console.log(res)
      $('#imgfile').attr('src',res.url)
    }
  })
})

接着我们在后端定义一个文件上传的api接口,我们前面已经安装了multer插件,可以直接使用,我们接口地址定义在routes/user.js文件中,具体代码如下所示:

var express = require('express');
// 引入文件上传的插件
var m = require('multer');
​
// 引入文件模块
var fs = require('fs');
​
var router = express.Router();
​
// 自己创建目录
// 调用的是上传文件中的一个属性dest,这个属性就是用来指定上传的目录,如果不存在将会自动创建
//dest中的参数:就是路径
var upload = m({dest:"./public/uploads"});
​
​
​
/* GET users listing. */
router.get('/', function(req, res, next) {
  res.send('respond with a resource');
});
​
// req.body 接收post提交的数据 req.query是get
// single是用来接收文件上传的信息
// 该方法中的参数,需要和前端formdata.append('名称'),需要保持一致
// imgfile 需要和append('名称')一样
router.post('/upload',upload.single('imgfile'),function(req,res){
  // console.log(req.file)  //可以接收到文件的信息
​
  // ./public/upload/ashfalsflaskjfas
  var oldfile = req.file.destination+'/'+ req.file.filename;
  var newfile = req.file.destination+'/'+ req.file.originalname;        //./public/upload/asdasd.jpg
​
  // 文件重命名
  // fs.rename('旧文件','新文件名',function(){})
​
  fs.rename(oldfile,newfile,function(err){
    if(err){
      res.send({
        code:'400',
        msg:'上传失败'
      })
    }else{
      res.send({
        code:'200',
        msg:'上传成功',
        url:'/uploads/'+req.file.originalname
      })
    }
  })
})
​
module.exports = router;
​

6.1.5 文件上传后的预览效果

前面我们后端的Api接口以后写好了,接下来我们看看前端Ajax的请求,前端我们在reg.html中写,给上传文件的文本框绑定一个change事件,

$('#img').change(function(){
  // 获取文件上传的信息
  // console.log(this.files[0])
​
  // 文件上传必须要使用formData对象
  var formdata = new FormData();
  // 调用formdata中有个方法 append 追加的意思
​
  //把文件上传的信息添加到了formdata对象中,属性名是imgfile 属性值:当前文件信息
  // {imgfile:as;dja;sdj;asd}
  formdata.append('imgfile',this.files[0]);
​
​
  // 发送ajax
  $.ajax({
    // 访问users路由文件下的upload路由
    url:'/users/upload',
    type:'post',
    data:formdata,  //传递文件上传的对象
​
    // 一旦文件上传,必须要有这个两个属性。如果没有将会报错
​
    // 文件上传的时候,内存处理中是以二进制的方式去上传
    // 正常的是数据处理,在发生ajax的时候,一般都是把数据转换为字符串进行传递的。
    // processData该属性的值默认为true,就是以字符串的形式传递。false,不以字符串的形式传递
    processData:false,
​
    // 更改数据的类型,默认为true,改为为false就是不使用默认的形式
    contentType:false,
​
    success:function(res){
      // console.log(res)
      $('#imgfile').attr('src',res.url)
    }
  })
})

我们需要获取文件上传的对象,然后请求上传文件的Api接口地址,post请求,具体代码如下。

​
success:function(res){
  // console.log(res)
  $('#imgfile').attr('src',res.url)
}

执行完以后我们可以获取服务端返回的上传成功的通知,文件也上传到express的public/uplods文件夹下。

前端这边我们上传完的图片需要预览,其实就是把接受返回的url地址加到预览图片img标签的src属性上,修改一下上传的ajax代码如下所示:

效果如下所示:

6.2 同源策略

6.2.1 什么是同源

什么是同源策略?

同源策略:是浏览器的一个限制,安全限制
什么是同源
    协议相同
    域名相同
    端口相同
三个相同,才能在这个网站里面进行随意的浏览和请求
跨域
vue
    localhost:8080
node
    localhost:3000

我们来看一下比较:

URL1URL2概述是否允许通信
http://www.foo.com/js/a.jshttp://www.foo.com/js/b.js协议、域名、端口都相同允许
http://www.foo.com/js/a.jshttp://www.foo.com:8888/js/b.js协议、域名相同、端口不同不允许
https://www.foo.com/js/a.jshttp://www.foo.com/js/b.js域名相同、端口相同、协议不同不允许
http://www.foo.com/js/a.jshttp://www.bar.com/js/b.js协议、端口相同、域名不同不允许
http://www.foo.com/js/a.jshttp://foo.com/js/b.js协议、端口相同、主域名相同、子域名不同不允许
注意:
同源策略限制的不同源之间的交互主要针对的是js中的XMLHttpRequest等请求,写代码的时候也常常会引用其他域名的js文件,样式文件,图片文件什么的,这些则不会收到限制

6.2.2 同源策略的目的

我们前面看到了,同源策略的限制访问条件还是挺多了,说白了就是只允许自己访问自己的网站,那么浏览器为什么会有同源策略呢?他的主要目的是什么呢?

同源策略的目的:就是为了安全性

没有同源策略,ajax请求数据很危险

ajax主要是通过请求数据的。如果没有同源策略的影响,ajax可以任意的请求数据
    不管是京东、天猫、拼多多、唯品会....
ajax
    从你本地出发,从你的本地服务器出发
        www.localhost.com:8080
    请求京东的
        www.jd.com

6.2.3 Ajax请求限制

ajax收同源策略限制

我们知道ajax请求Api接口的时候受同源策略的限制,具体比如我们直接使用浏览器打开html页面,请求node后端定义的Api接口就会出现跨域的问题,效果如下。

什么是跨域呢?

两个网址之间的请求,如果有一方不同意,那就会产生跨域
  1. cors方法,后台方法

    cnpm i cors --save
    ​
    //下载依赖之后,需要在后端进行配置
    vue的时候,告诉你们如何配置
  2. 后续Vue中解决跨域一般我们使用的代理的方式来解决,也就是我们把Vue底层服务作为跳板代理请求接口,这样就解决跨域的问题了,相当于找了个中介。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值