And*_*rew 13 ruby-on-rails http-post ruby-on-rails-3
我正在努力实现Ajax-Upload以在我的Rails 3应用程序中上传照片.文件说:
对于IE6-8,Opera,其他浏览器的旧版本,您可以像通常使用常规的基于表单的上传一样获得该文件.
对于使用进度条上传文件的浏览器,您需要获取原始发布数据并将其写入文件.
那么,我如何在控制器中接收原始发布数据并将其写入tmp文件,以便我的控制器可以处理它?(在我的情况下,控制器正在进行一些图像处理并保存到S3.)
一些额外的信息:
正如我现在配置的那样,帖子正在传递这些参数:
Parameters:
{"authenticity_token"=>"...", "qqfile"=>"IMG_0064.jpg"}
Run Code Online (Sandbox Code Playgroud)
...并且CREATE操作如下所示:
def create
@attachment = Attachment.new
@attachment.user = current_user
@attachment.file = params[:qqfile]
if @attachment.save!
respond_to do |format|
format.js { render :text => '{"success":true}' }
end
end
end
Run Code Online (Sandbox Code Playgroud)
...但我收到此错误:
ActiveRecord::RecordInvalid (Validation failed: File file name must be set.):
app/controllers/attachments_controller.rb:7:in `create'
Run Code Online (Sandbox Code Playgroud)
Ste*_*man 27
这是因为params [:qqfile]不是UploadedFile对象,而是包含文件名的String.文件的内容存储在请求的主体中(可以使用request.body.read访问).当然,你不能忘记向后兼容性,所以你仍然需要支持UploadedFile.
因此,在您以统一的方式处理文件之前,您必须捕获这两种情况:
def create
ajax_upload = params[:qqfile].is_a?(String)
filename = ajax_upload ? params[:qqfile] : params[:qqfile].original_filename
extension = filename.split('.').last
# Creating a temp file
tmp_file = "#{Rails.root}/tmp/uploaded.#{extension}"
id = 0
while File.exists?(tmp_file) do
tmp_file = "#{Rails.root}/tmp/uploaded-#{id}.#{extension}"
id += 1
end
# Save to temp file
File.open(tmp_file, 'wb') do |f|
if ajax_upload
f.write request.body.read
else
f.write params[:qqfile].read
end
end
# Now you can do your own stuff
end
Run Code Online (Sandbox Code Playgroud)
试试吧,添加lib/qq_file.rb:
# encoding: utf-8
require 'digest/sha1'
require 'mime/types'
# Usage (paperclip example)
# @asset.data = QqFile.new(params[:qqfile], request)
class QqFile < ::Tempfile
def initialize(filename, request, tmpdir = Dir::tmpdir)
@original_filename = filename
@request = request
super Digest::SHA1.hexdigest(filename), tmpdir
fetch
end
def self.parse(*args)
return args.first unless args.first.is_a?(String)
new(*args)
end
def fetch
self.write @request.raw_post
self.rewind
self
end
def original_filename
@original_filename
end
def content_type
types = MIME::Types.type_for(@request.content_type)
types.empty? ? @request.content_type : types.first.to_s
end
end
Run Code Online (Sandbox Code Playgroud)
在assets_controller中输入:
def create
@asset ||= Asset.new(params[:asset])
@asset.assetable_type = params[:assetable_type]
@asset.assetable_id = params[:assetable_id] || 0
@asset.guid = params[:guid]
@asset.data = QqFile.parse(params[:qqfile], request)
@asset.user_id = 0
@success = @asset.save
respond_with(@asset) do |format|
format.html { render :text => "{'success':#{@success}}" }
format.xml { render :xml => @asset.to_xml }
format.js { render :text => "{'success':#{@success}}"}
format.json { render :json => {:success => @success} }
end
end
Run Code Online (Sandbox Code Playgroud)
JavaScript的:
var photo_uploader = new qq.FileUploader({
element: document.getElementById('photo-button'),
multiple: true,
action: '/assets',
allowedExtensions: ['png', 'gif', 'jpg', 'jpeg'],
sizeLimit: 2097152,
params: {guid: $('#idea_guid').val(), assetable_type: 'Idea', klass: 'Picture', collection: true}
});
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
22058 次 |
| 最近记录: |