关于浏览器如何在页面上显示准备上传的图片的问题

页面如何通过input标签来显示获取的图片?

之所想到这个问题是因为某次做动画的时候,需要获取transform-origin的值,普通的left,right,center,top和bottom已经满足不了需求,就想到了将图片显示出来,获取点击的地方占图片的百分比来找到变形的中心点

有了这个想法之后,大致的步骤就出来了

  • 首先在html中写一个<input type =" file"/> 的标签
  • 然后在html中写一个img标签
  • 在JS中获取input的dom元素,通过value值来获取路径
  • 将路径放在img的src属性中

那么问题来了,真的能通过value的值来获取到路径吗?

答案是否定的,不然问题也就迎刃而解了不是吗?

这里我们不得不提到一个问题,那就是浏览器基于保护用户的相关安全措施,将真实路径隐藏了起来,而使用时 fakepath+文件名 的形式来代替这个真实的路径。

这里然我们来看个动图来看看到底是个什么鬼

getFilePath.gif

我们能在动图中看到我上传的图片明明是 D盘=》图片=》p站 这个目录下,最后console.log()出来的结果居然是 C:\fakepath\58649812_p1_master1200.jpg

什么鬼?为什么会这样?

其实我们打印出来的值,正是浏览器的保护用户的相关措施,具体情况我也不甚了解,但是我发现了一个惊天大秘密。我的IE居然可以通过这个方法获取到图片。并且我测试了IE8,9,10,11。都是可以拿到值的。

难道修改浏览器的某些配置就能获取到了吗?

根据我的推测,应该是可以拿到值的,但是遨游在英特网的海洋的中,谁会嫌安全措施多了呢?既然浏览器为了用户安全,给你禁止了一些功能,自然是为了让用户能够在一个相对安全的网络环境中遨游嘛。也许你不知道这些安全措施有多重要,这里小提到一个跨域问题,后面我会谈到一个解除浏览器的跨域限制,来让大家看看安全措施的重要性。

那么问题又来了,既然input获取不到,又不让我改浏览器,那到底怎么办呢?

这里我们用到两种方式来解决这个问题
  1. 通过ajax传值到后台,后台获取数据后拿到文件名,然后将图片放到一个新的路径下,将路径返回给我们的JS,再利用JS来操作DOM让图片显示出来(这里我们用php来举个例子)
  2. 利用H5中的FileReader()对象

在具体怎么实现之前,让我们来看看我们从本地拿进来的图片到底在input的哪里

input的这个dom元素到底有什么.gif

我们可以看到input这个对象下面的files属性下面有我们想要的文件名,文件格式。


既然已经拿到了我们想要的东西,那么就开工了。

  • 通过ajax加上后台来实现让页面上显示图片
    • HTML部分
      <input type="file" >
      <br />
      <img src="" alt="">
    
    • JS部分
          // 获取input的dom元素
          var inputObj = document.querySelector('input');
          // 获取img的dom元素
          var imgObj = document.querySelector('img');
          // 监听input的改变
          inputObj.onchange = function(){
              // 拿到文件的信息
              var pic = inputObj.files[0];
    
              // 创建一个formData对象
              var formData = new FormData();
              // 将文件信息存入这个对象中
              formData.append('file',pic);
    
              // 创建异步对象
              var xhr = new XMLHttpRequest();
    
              // 设置method和url 
              xhr.open('post','getFilePath.php');
    
              // 发送请求,将formData这个对象传递
              xhr.send(formData);
    
              // 监听状态
              xhr.onreadystatechange = function(){
                  // 如果请求已完成,并且成功找到网页,就拿到路径值使用
                  if(xhr.readyState == 4 && xhr.status == 200){
                      // 获取返回值
                      var src = xhr.responseText;
                      // 改变img标签的src值
                      imgObj.src=src;
                  }
              };
    
          };
    
    • php部分
      // 获取文件名
      $fileName = $_FILES['file']['name'];
      // 获取暂存的路径
      $tempPath = $_FILES['file']['tmp_name'];
      // 定义将要保存的路径 ,你要保证你当前文件下有images这个文件夹
      $savePath = 'images/'.$fileName;
    
      // 将图片移动到指定位置
      move_uploaded_file($tempPath, $savePath);
      // 返回路径
      echo $savePath;
    

我去,就为了显示张图片而已,还得需要后台来配合,太麻烦了。真有种杀猪用了牛刀的感觉。想想就觉得不爽。所以这里推荐使用FileReader()来实现功能

  • 通过FileReader()对象来让页面显示图片
    • HTML
      <input type="file" name="">
      <br />
      <img src="" alt="">
    
    • JS
      // 获取input的dom元素
          var inputObj = document.querySelector('input');
          // 获取img的dom元素
          var imgObj = document.querySelector('img');
          // 监听input发生改变
          inputObj.onchange = function(){
              // 获取上传的文件信息
              var pic = inputObj.files[0];
    
              // 创建FileReader对象
              var reader = new FileReader();
    
              // 编码成Data URL (这一步最为关键)
              reader.readAsDataURL(pic);
    
              // 监听上传完成
              reader.onload = function(){
                  // 拿到base64的路径
                  var src = reader.result;
                  // 改变img的src属性值
                  imgObj.src=src;
              }
    
          };
    

这样一比较,代码是不是少了很多?根本不需要什么后台和ajax,就能让图片显示。
这完全可以用在你要上传图片的时候,让图片预先在页面上预览,然后再一次性提交给后台。

结语

  • 首先想说的是 第一次用markdown写东西。并不是很会用。所以写的排版方面很是奇怪。只是希望看到人不要打我。。。。
  • 然后 我还在前端这个泥坑里面摸爬滚打,所以写的东西有很多不足的地方,如果有什么错误的地方,还望见谅。
  • 最后想说的是 H5 给我们真的提供的不少便利的东西,善用里面的属性和方法会给我们的开发带来很多的便利。
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • Ajax和XMLHttpRequest 我们通常将Ajax等同于XMLHttpRequest,但细究起来它们两个是...
    changxiaonan阅读 2,217评论 0 2
  • 最近有几个问题一直被提及,就是图片上传这一块,虽然之前也说过,今天对这部分内容进行一个归纳和整理. 1.自定义in...
    殷灬商阅读 3,281评论 1 8
  • H5 meta详解 viewport width:控制 viewport 的大小,可以指定的一个值,如果 600,...
    FConfidence阅读 800评论 0 3
  • 工厂模式类似于现实生活中的工厂可以产生大量相似的商品,去做同样的事情,实现同样的效果;这时候需要使用工厂模式。简单...
    舟渔行舟阅读 7,717评论 2 17