天天看点

图片预览,图片上传(ajax,axios两种方式)

一 图片文件转成临时的URL预览

首先,在网页里面图片可以直接拖到浏览器里面显示,但是也打开了新的网页,为了让图片就在当前网页内显示,那么必须上传或则拖拉当当前网页,然后再经过处理,就能显示出来了.

关于文件对象的知识点:

/*
	**一  File 对象代表一个文件,用来读写文件信息。

	File 对象有以下实例属性:
	File.lastModified:最后修改时间
	File.name:文件名或文件路径
	File.size:文件大小(单位字节)
	File.type:文件的 MIME 类型

	**二  FileList 对象
	FileList对象是一个类似数组的对象,代表一组选中的文件,
	每个成员都是一个 File 实例。
	
	/*************重要点*****************************/
	 *1. 文件控件节点(<input type="file">)的files属性,
	返回一个 FileList 实例。
    
    *2.拖拉一组文件时,目标区的DataTransfer.files属性,
    返回一个 FileList 实例
	/*********************************************/

	**3 FileReader 对象 (本例中不用暂时不讲)
*/
           

在上传文件的input标签中会有files属性,其他的input标签是没有的.

// HTML 代码如下
// <input id="fileItem" type="file">
var files = document.getElementById('fileItem').files;
files instanceof FileList // true
           

关于URL对象的知识点

/*
	URL 实例的属性:
		URL.href:返回整个 URL
		URL.protocol:返回协议,以冒号:结尾
		URL.hostname:返回域名
		URL.host:返回域名与端口,包含:号,默认的80和443端口会省略
		URL.port:返回端口
		URL.origin:返回协议、域名和端口
		URL.pathname:返回路径,以斜杠/开头
		URL.search:返回查询字符串,以问号?开头
		URL.searchParams:返回一个URLSearchParams实例,该属性是Location对象没有的
		URL.hash:返回片段识别符,以井号#开头
		URL.password:返回域名前面的密码
		URL.username:返回域名前面的用户名

	URL对象的方法:
	
	URL.createObjectURL(文件对象)方法用来为上传/下载的文件、流媒体文件
	生成一个 URL 字符串。这个字符串代表了File对象或Blob对象的 URL。
	
	URL.revokeObjectURL()方法用来释放URL.createObjectURL方法生成
	的 URL 实例。它的参数就是URL.createObjectURL方法返回的 URL 字符串。
*/
           

好了,我们现在拉看下:图片的预览功能实现:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 550px;
            margin: 150px auto;
        }

        input {
            height: 20px;
            margin-bottom: 10px;
            border: 1px solid #000;
        }

        .imgShow {
            width: 500px;
            height: 400px;
            border: 5px solid #000; 
        }
    </style>
</head>
<body>

    <div class="box">
        <!-- 利用label标签可以美化上传按钮 -->
        <label for="fileBtn" class="uploadFile">上传文件</label>
        <input type="file" id="fileBtn" style="display: none">
        <div class="imgShow"></div>
        <img src="" alt="">	
    </div>

</body>
</html>
<script>
    document.getElementById('fileBtn').onchange = function(){

        //获取到文件
        console.log(this.files[0]);
        // console.dir(this);

        //限制上传的代码格式与大小
        var fileSize = this.files[0].size 
        var size = fileSize / 1024

        if(size>2000){  
            alert("附件不能大于2M");
            return
        }

        //限制上传的文件格式
        var name = this.files[0].name;
        var fileName = name.substring(name.lastIndexOf(".")+1).toLowerCase();
        if(fileName !="jpg" && fileName !="jpeg" && fileName !="pdf" 
            && fileName !="png" && fileName !="dwg" && fileName !="gif" ){
            alert("请选择图片格式文件上传(jpg,png,gif,dwg,pdf,gif等)!");
            this.files[0].name = "";
            return
        }

        // 将文件生成一个url路径字符串
        var url = URL.createObjectURL(this.files[0]);

        // 将图片展示在div的盒子里面
         document.querySelector('.imgShow').style.background = "url("+ url + ") no-repeat center/cover";
	
		//也可以将图片显示在img单标签里面
		 document.querySelector('img').src = url;
    }
</script>
           
图片预览,图片上传(ajax,axios两种方式)

注意点:

/*1.这里利用了onchange事件,因为只有当input里面的图片内容改变的时
候我们才出发

2.var url = URL.createObjectURL(this.files[0]);用来生成
的是图片的临时路径blob:null/9fbf5462-b229-45c2-9c0b-19091d063a91

3.这种方式生成的路劲是临时的,不会长久保存,所以下次打开浏览器是观察
不到图片的
*/
           

二 图片文件上传到服务器预览

因为图片要经过服务器,所以需要php代码来操作服务器.整体思路是通过ajax将图片文件传给服务器,服务器再生成一个路径通过响应体返回给前端使用.

图片预览,图片上传(ajax,axios两种方式)

前端代码:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <style>
        .box {
            width: 500px;
            height: 550px;
            margin: 150px auto;
        }

        input {
            height: 20px;
            margin-bottom: 10px;
            border: 1px solid #000;
        }

        .imgShow {
            width: 500px;
            height: 400px;
            border: 5px solid #000; 
        }
    </style>
</head>

<body>

    <div class="box">
        <input type="file" id="fileBtn">
        <div class="imgShow"></div>
    </div>

</body>

</html>

<script>
    document.getElementById('fileBtn').onchange = function () {

        //这是传入的内容是空
        var fm = new FormData();
        //给fm对象添加文件内容
        fm.append('icon',this.files[0]);

        //发送ajax请求
        var xhr = new XMLHttpRequest();
        //设置请求行
        xhr.open('post','getUrl.php');
        //发送数据
        xhr.send(fm);
        //监听事件完成
        xhr.onreadystatechange = function(){
            if(xhr.readyState == 4 && xhr.status == 200) {
                
                // console.log(xhr.responseText);
  document.querySelector('.imgShow').style.background = "url("+ xhr.responseText +") no-repeat center/cover";
            }
        }
    }
</script>
           

后端代码:

<?php 

    $icon = $_FILES['icon'];

    $name = $icon['name'];

    $tmp = $icon['tmp_name'];

    $gbkName = iconv('utf-8','gbk',$name);

    move_uploaded_file($tmp,"upload/$gbkName");

    //要返回路径!!!
    echo "upload/$name";
?>
           

因为经过了服务器,所以此路径是长期有效的.只需要请求服务器拿到即可.

三 拖拽预览

最后一个小demo:利用图片的预览的技术,现在将图片拖拽到浏览器里面显示:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>

    <style>
        .box {
            width: 600px;
            height: 500px;
            margin: 100px auto;
            border: 10px solid #000;
        }
    </style>
</head>

<body>
    <div class="box">请拖入图片</div>
</body>

</html>

<script>
    //这个事件只是为了让ondrop可以被触发
    document.ondragover = function (e) {

        e = e || window.event;
        e.preventDefault();
    }

    //这个事件默认不会触发
    document.ondrop = function (e) {

        e = e || window.event;
        e.preventDefault();
    }

	/***********上面的代码是为了阻止浏览器默认打开图片的操作***********/
	
    document.querySelector('.box').ondragover = function (e) {
        e = e || window.event;
        e.preventDefault();
    };

    document.querySelector('.box').ondrop = function (e) {

        e = e || window.event;
        e.preventDefault();

        console.log(e.dataTransfer.files);

        //把拖进来的文件转成临时路径
        var url = URL.createObjectURL(e.dataTransfer.files[0]);
        //并显示在页面上
        this.style.background = "url(" + url + ") no-repeat center /cover";

    }
</script>
           

最终效果:

图片预览,图片上传(ajax,axios两种方式)

四 axios上传图片

4.1 axios的简介

axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端,它本身具有以下特征:

  1. 从浏览器中创建 XMLHttpRequest
  2. 从 node.js 发出 http 请求
  3. 支持 Promise API
  4. 拦截请求和响应
  5. 转换请求和响应数据
  6. 取消请求
  7. 自动转换JSON数据
  8. 客户端支持防止 CSRF/XSRF

4.1.1 使用方式

$ npm install axios
$ cnpm install axios //taobao源
$ bower install axios
或者使用cdn:
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
           

4.2 axios上传图片

原理: 利用表单中的FormData对象来实现,其作用是:表单数据以键值对的形式向服务器发送,这个过程是浏览器自动完成的。但是有时候,我们希望通过脚本完成过程,构造和编辑表单键值对,然后通过XMLHttpRequest.send()方法发送。浏览器原生提供了 FormData 对象来完成这项工作。也就是说我们可以利用FormData对象中的一些方法来构造和编辑表单键值对.

使用到的方法:

FormData.append(key, value):添加一个键值对。如果键名重复,则会生成两个相同键名的键值对。如果第二个参数是文件,还可以使用第三个参数,表示文件名。

4.2.1 axios上传图片步骤:

// 1. 获取到上传的文件
// 2. 创建form对象,将文件内容添加到form对象中
// 3. 设置请求头
// 4. 发送请求  
           

具体实现:

<input  name="file" type="file" onclick="uploadpic(event)"/>
 
<script type="text/javascript">
function uploadpic(e){
	 //1. 获取到上传的文件
      var self = this
      console.log(e.target);
      let file = e.target.files[0]
      
      //2. 创建form对象,将文件内容添加到form对象中
      let param = new FormData()  // 创建form对象
      param.append('file', file, file.name)  // 通过append向form对象添加数据
      console.log(param.get('file')) // FormData私有类对象,访问不到,可以通过get判断值是否传进去

	  // 设置请求头
      let config = {
        headers: {'Content-Type': 'multipart/form-data'}
      }
      
     // 添加请求头,发送请求头
     const url = "自己的请求地址"
     axios.post(url, param, config).then(response => {
       
       	  //打印请求成功后返回的值
          console.log(response.data)   
}
</script>

           

继续阅读