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";
- 1
- 2
<input className="form-control" name={form_input_name} id={form_input_id} ref="urlinput" value={this.state.url || ""} onChange={this.handleUrlChange}/>
- 1
- 二,使用
<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>
- 1
- 2
- 3
.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;
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 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
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
代码同样简单,构建文件路径,保存文件,返回路径。因为开发进度的原因这里并没有对图片的大小和类型进行修改(为了减少数据传输量,在前端进行大小的修改比较合理),后面review这部分代码的时候会再更新这篇博客。
值得说说的是:
- 图片命名的问题,采用了时间戳,命名不会重复,为了方便管理,将不同类型的图片存于不同的文件夹,但是只以时间戳命名可获取的信息太少,不利于运营人员管理,后期会再仔细考虑这个问题。
- 存放路径问题,在后端代码里,rails能将图片存在rails项目文件夹的任何位置,但是客户端显示图片的时候,只能访问public文件夹里的内容,于是决定将图片存在public文件夹下。
三,总结及思考
完成这个功能不需要太久,但代码外的思考不少。图片小,甚至能用Git备份图片,也许不是长久之计,开始想念aws的好了,容灾交给aws处理最好不过了,后面试了一下AWS S3
希望自己写得越多,考虑得越远。
在家的第十天,日子过得还是那么快,终于还是有点慌。接触的东西越多,要学的就越多,兴奋之余隐隐感觉时间不够用。既然梦想着成为一名全栈工程师,就理应付出更多。
ruby on rails爬坑(三):图片上传及显示的更多相关文章
- 从零开始学习Node.js例子三 图片上传和显示
index.js var server = require("./server"); var router = require("./router"); var ...
- 图片上传即时显示javascript代码
这是基于javascript的一种图片上传即时显示方法,测试结果IE6和火狐浏览器可以正常使用.google浏览器不兼容. 这种方法兼容性比较差,仅供参考,建议使用ajax方法来即时显示图片. 1.首 ...
- 图片上传并显示(兼容ie),图片大小判断
图片上传并显示(兼容ie),图片大小判断 HTML <div id="swf" style="margin: 0 auto;text-align: center;& ...
- ueditor图片上传和显示问题
图片上传: 这段是contorller代码 @RequestMapping(value = "/uploadImg", method = RequestMethod.POST) @ ...
- 图片上传和显示——上传图片——上传文件)==ZJ
http://www.cnblogs.com/yc-755909659/archive/2013/04/17/3026409.html aspx上传 http://www.cnblogs.com/mq ...
- 安卓自定义View实现图片上传进度显示(仿QQ)
首先看下我们想要实现的效果如下图(qq聊天中发送图片时的效果): 再看下图我们实现的效果: 实现原理很简单,首先我们上传图片时需要一个进度值progress,这个不管是自己写的上传的方法还是使用第三方 ...
- 【Jersey】图片上传及显示
一.前期准备 图片上传需要用到的一些依赖: <dependency> <groupId>org.jvnet.mimepull</groupId> <artif ...
- struts中用kindeditor实现的图片上传并且显示在页面上
做公司网站的时候由于需要在内容属性中加入图片,所以就有了这个问题,本来一开始找几篇文章看都是讲修改kindeditor/jsp/file_manager_json.jsp和upload_json.js ...
- MVC图片上传并显示缩略图
前面已经说了怎么通过MVC来上传文件,那么这次就说说如何上传图片然后显示缩略图,这个的实用性还是比较大.用UpLoad文件夹来保存上传的图片,而Temp文件夹来保存缩略图,前面文件上传部分就不再重复了 ...
随机推荐
- DataSnap 2009 系列之三 (生命周期篇)
DataSnap 2009 系列之三 (生命周期篇) DataSnap 2009的服务器对象的生命周期依赖于DSServerClass组件的设置 当DSServer启动时从DSServerClass组 ...
- ubuntu 14.04 重复登录问题解决方法
为了远程登录,装了xubunt后出现重复登录的问题,尝试了多种方法,后来用下面的命令解决了 chown username:username .Xauthority 参考资料:http://askubu ...
- unity3d游戏开发git环境配置
http://dmayance.com/git-and-unity-projects/ 主要是将2进制的项目文件设置成文本模式,这样便于比较修改. 部署了一个gitignore,忽略了不需要同步的项目 ...
- android 术语
Context : 是android 应用程序的 中央控制中心.所有应用程序特有的功能通过context 进行访问. Activity: 一个 Android 应用有若干个 task 任务组成,每个人 ...
- 控制台telnet连接后无法关闭
按下ctrl+]然后再quit就可以close connection
- MYBATIS 文档
http://www.mybatis.org/mybatis-3/zh/index.html
- python通过自定义异常,提前退出方法
python退出的操作,搜索后都是return.exit()等 return:退出一个方法,并返回一个值 exit():退出python 想要实现的功能: 方法A中调用多个方法,方法B.方法C.. ...
- 用Redis构建分布式锁-RedLock(真分布)
在不同进程需要互斥地访问共享资源时,分布式锁是一种非常有用的技术手段. 有很多三方库和文章描述如何用Redis实现一个分布式锁管理器,但是这些库实现的方式差别很大,而且很多简单的实现其实只需采用稍微增 ...
- JSP(include指令与<jsp:include>动作的区别)
<%@ page language= "java" contentType="text/html;charset=UTF-8" %><html ...
- 数据转移发现font有问题
本地正常 以为是mime.types没有 但是发现是存在的 然后根据提示百度了很久都没有解决 解决: 去字体官网下载改字体文件下来 上传到服务器 发现可以正常访问 说明不是服务器的问题 有个提示 i ...