ruby on rails爬坑图片上传及显示的实例

一,问题及思路

最近在用 rails + react + mysql 基本框架写一个cms + client的项目,里面涉及到了图片的上传及显示,下面简单说说思路,至于这个项目的配置部署,应该会在寒假结束总结分享一下。

rails中图片上传及显示要解决主要问题是:

图片存在哪?
图片格式大小?
客户端怎么显示图片?
因为这是个小项目,估计最多1000张图片,最多占用空间1G,所以采取相对简便的方法: 图片保存在rails的public文件夹里(也就是保存在部署该项目的主机中) ,如果图片比较多的话,还是推荐用亚马逊云提供的服务 AWS S3 (理解为一个硬盘,S3提供了接口给你存取东西,安全,管理方便)。

大概的思路是,前端通过 <input type="file"/> 选择文件,发送ajax请求到后端的controller,controller将请求的图片数据进行大小裁剪、类型转换后保存到本地指定的文件夹,同时将路径返回,用于显示图片。

二,实践

思路比较简单,所以话不多说,直接上代码:

前端代码整合在react写的一个图片上传组件里,image_uploader.js.jsx代码如下

var ImageUploader = React.createClass({
  getInitialState: function() {
    return {
      url: this.props.url
    };
  },
  onFileSelect: function(e) {
    var that = this;
    var files = e.target.files;
    if (files.length <= 0) {
      AlertModal.showWithProps("No file selected");
      return;
    }
    var data = new FormData();
    $.each(files, function(key, value) {
      data.append('file', value);
      data.append('type', that.props.type)
    });
    this.upload(data);
  },
  upload: function(data) {
    var that = this;
    if (!data) {
      return;
    } else {
      this.refs.filebtn.disabled = true;
      $("#loading-modal").modal('show');
      $.ajax({
        url: '/missions/upload_image',
        type: 'post',
        data: data,
        processData: false,
        contentType: false
      }).done(function(res){
        console.log(res);
        that.setState({url: res.url});       
      }).fail(function(err){
        console.log(err);
        AlertModal.showWithProps("Upload Failed");
      }).always(function(){
        $("#loading-modal").modal('hide');
        that.refs.filebtn.disabled = false;
      });
    }
  },
  handleUrlChange: function(e) {
    this.setState({url: e.target.value});
  },
  render: function() {
    var form_input_name = this.props.model + "[thumb]";
    var form_input_id = this.props.model+ "_thumb";
    return (
      <div className="image-uploader-inputs row">
        <div className="col-sm-8 image-input">
          <input className="form-control" name={form_input_name} id={form_input_id} ref="urlinput" value={this.state.url || ""} onChange={this.handleUrlChange}/>
        </div>
        <div className="btn btn-primary btn-file image-input-btn">
          <input type="file" onChange={this.onFileSelect} ref="filebtn"/>
        </div>
      </div>
    );
  }
});

上面的重点在于upload函数,源码是最好的文档,如果看源码需要太多注释的话,那肯定是我写的代码质量还不够高,请批评指出。

写这个的时候遇到两个问题:

一,这个组件是用在_form.html.slim里的,这个表单是用于信息的录入的,大家对表单应该比较熟悉,既然要用在表单里,就是给这个组件作标识,标明name和id,代码片段如下(从上面的代码中截取):
var form_input_name = this.props.model + "[thumb]";
var form_input_id = this.props.model+ "_thumb";
<input className="form-control" name={form_input_name} id={form_input_id} ref="urlinput" value={this.state.url || ""} onChange={this.handleUrlChange}/>
二,使用 <input type="file"/> 有一个普遍的问题,自带的UI不美观。

谷歌/百度“input file btn”会有许多解决方案,家里网速差就没细看。我的做法是把这个btn设为透明,相关的代码及css如下:

<div className="btn btn-primary btn-file image-input-btn">
  <input type="file" onChange={this.onFileSelect} ref="filebtn"/>
</div>
.image-input-btn {
    float: left;
    width: 15%;
    background-image: image-url("upload.png");
    background-size: 30px;
    background-position: center;
    background-repeat: no-repeat;
    input {
      //hide file input button
      width: inherit;
      opacity: 0;
    }
  }
10
11
12
13
接下来看看后端的代码:

def upload_image
    # => will resize later
    image_relative_path = "/assets/images/#{params[:type]}/#{Time.now.to_i}.png"
    image_path = File.expand_path(File.dirname(__FILE__) + '/../..') + "/public" + image_relative_path

    data = File.read(params[:file].path)
    img = File.new(image_path, "w+")
      if img
        img.syswrite(data)
      end
    img.close
    render json: {url: image_relative_path}
 end
10
11
12
13
代码同样简单,构建文件路径,保存文件,返回路径。因为开发进度的原因这里并没有对图片的大小和类型进行修改(为了减少数据传输量,在前端进行大小的修改比较合理),后面review这部分代码的时候会再更新这篇博客。

值得说说的是:

图片命名的问题,采用了时间戳,命名不会重复,为了方便管理,将不同类型的图片存于不同的文件夹,但是只以时间戳命名可获取的信息太少,不利于运营人员管理,后期会再仔细考虑这个问题。
存放路径问题,在后端代码里,rails能将图片存在rails项目文件夹的任何位置,但是客户端显示图片的时候,只能访问public文件夹里的内容,于是决定将图片存在public文件夹下。
三,总结及思考

完成这个功能不需要太久,但代码外的思考不少。图片小,甚至能用Git备份图片,也许不是长久之计,开始想念aws的好了,容灾交给aws处理最好不过了,后面试了一下AWS S3

时间: 2024-09-16 23:41:56

ruby on rails爬坑图片上传及显示的实例的相关文章

js HTML5多图片上传及预览实例解析(不含前端的文件分割)_javascript技巧

本文实例为大家分享了js HTML5多图片上传及预览实例,供大家参考,具体内容如下 主要运用  1.HTML5 files可以选择多文件,以及获取多文件信息  2.XMLHTTPRequest对象,发送HTTP传输请求  3.将每一个文件放在FormData,进行传输  4.利用readAsDataURL将图片内容直接变成url,放在img标签的src当中,生成可预览的图片  html+css+js代码  <!DOCTYPE html> <head> <meta http-e

c#图片上传和显示的实现方法_C#教程

由于需要图片上传的功能,所以花了一些时间网上找相关资料终于搞定,效果图如下: 下面的是解决方案截图和上传的图片截图: 具体实现代码如下: 1.界面代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UploadPic.aspx.cs" Inherits="Pic_Try.UploadPic" %> <!DOCTYPE html PUBLIC

PHP实现原生态图片上传封装类方法_php实例

PHP图片上传类,经典方式,不过上传效率还算可以,我自己用过的一个类,当时对这个类做了些修改,以满足自己特定功能的需要,对PHP熟悉的,可对这个上传类做优化和修改,后附有调用方法,让PHP开发者上传图片轻松容易就做到,先上类代码: <?php class FileUpload_Single { //user define ------------------------------------- var $accessPath ; var $fileSize=200; var $defineTy

图片上传即时显示缩略图的js代码_图象特效

<script language="javascript" type="text/javascript"> var allowExt = ['jpg', 'gif', 'bmp', 'png', 'jpeg']; var preivew = function(file, container){ try{ var pic = new Picture(file, container); }catch(e){ alert(e); } } //缩略图类定义 va

JSP中图片的上传与显示方法实例详解_JSP编程

本文实例讲述了JSP中图片的上传与显示方法.分享给大家供大家参考.具体如下: 1.引言 数据库应用程序,特别是基于WEB的数据库应用程序,常会涉及到图片信息的存储和显示.通常我们使用的方法是将所要显示的图片存在特定的目录下,在数据库中保存相应的图片的名称,在JSP中建立相应的数据源,利用数据库访问技术处理图片信息.但是,如果我们想动态的显示图片,上述方法就不能满足需要了.我们必须把图片存入数据库,然后通过编程动态地显示我们需要的图片.实际操作中,可以利用JSP的编程模式来实现图片的数据库存储和显

php 图片上传类代码_php实例

先来个简单的: 复制代码 代码如下: <? //http://www.jb51.net class upLoad{ public $length; //限定文件大小 public $file; //判断此类是用于图片上传还是文件上传 public $fileName; //文件名 public $fileTemp; //上传临时文件 public $fileSize; //上传文件大小 public $error; //上传文件是否有错,php4没有 public $fileType; //上传

关于图片上传和显示的问题,急用

问题描述 我在开发c/s结构系统,需要这样的功能:在一个window窗口里放入一个能够上传图片的控件就是让用户点击后在自己的机子上找到所需要的图片,然后通过这个控件保存到数据库中(SqlServer2005),然后再所需要的地方显示出来,请问在.net的window自带的控件怎样实现这样的功能呀,请给出详细代码和解释,谢谢,等待中 解决方案 解决方案二:好像系统没有带这功能的自带控件吧.解决方案三:怎么没人知道啊?解决方案四:http://blog.csdn.net/hank212解决方案五:我

ASP.NET图片上传实例(附源码)_实用技巧

由于需要图片上传的功能,所以花了一些时间网上找相关资料终于搞定,效果图如下: 下面的是解决方案截图和上传的图片截图: 下面是代码:1.界面代码 <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="UploadPic.aspx.cs" Inherits="Pic_Try.UploadPic" %> <!DOCTYPE html PUBLIC &qu

php+flash+jQuery多图片上传源码分享_php实例

flash+php多图片上传的源码,测试成功,一个经典的上传源码,为什么要用flash作为上传的组件呢,其实这里不仅仅是flash,另加了jquery的技术,这样做的目的是为了更好更方便的管理图片,使用过QQ空间进行上传图片的童鞋都知道,QQ空间的上传体验度很好,而且管理我们上传的图片非常的方便,使用的技术基本上就是flash与jquery技术了. flash+jquery是作为前端图片上传展示的,还需要与php的结合才能将图片上传到指定的目标,这里的php一共有两个文件,一个upload.ph