Skip to content

Commit 331ff48

Browse files
committed
Merge pull request #26 from duncanbeevers/middleware
Add X-Requested-With param and IFrame middleware
2 parents a261a47 + 3a5519c commit 331ff48

File tree

4 files changed

+73
-0
lines changed

4 files changed

+73
-0
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,12 @@ Require the stylesheet file to app/assets/stylesheets/application.css
4848

4949
*= require jquery.fileupload-ui
5050

51+
## Using the middleware
52+
53+
The `jquery.iframe-transport` fallback transport has some special caveats regarding the response data type, http status, and character encodings. `jquery-fileupload-rails` includes a middleware that handles these inconsistencies seamlessly. If you decide to use it, create an initializer that adds the middleware to your application's middleware stack.
54+
55+
Rails.application.config.middleware.use JQuery::FileUpload::Rails::Middleware
56+
5157
## [Example app](https://github.com/tors/jquery-fileupload-rails-paperclip-example)
5258
This app uses paperclip and twitter-bootstrap-rails
5359

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module JQuery
2+
module FileUpload
3+
module Rails
4+
class Middleware
5+
def initialize(app)
6+
@app = app
7+
end
8+
9+
def call(env)
10+
dup._call(env)
11+
end
12+
13+
def _call(env)
14+
@status, @headers, @response = @app.call(env)
15+
@request = Rack::Request.new(env)
16+
17+
if iframe_transport?
18+
@headers['Content-Type'] = 'text/html'
19+
[@status, @headers, self]
20+
else
21+
[@status, @headers, @response]
22+
end
23+
end
24+
25+
def each(&block)
26+
block.call(html_document_left) if iframe_transport?
27+
@response.each(&block)
28+
block.call(html_document_right) if iframe_transport?
29+
end
30+
31+
def iframe_transport?
32+
@request.params['X-Requested-With'] == 'IFrame'
33+
end
34+
35+
def html_document_left
36+
"<!DOCTYPE html><html><body><textarea #{metadata}>"
37+
end
38+
39+
def html_document_right
40+
"</textarea></body></html>"
41+
end
42+
43+
def metadata
44+
meta = {}
45+
meta['data-status'] = @response.status if @response.respond_to? :status
46+
meta['data-statusText'] = @response.status_message if @response.respond_to? :status_message
47+
meta['data-type'] = @headers['Content-Type'] if @headers.has_key?('Content-Type')
48+
meta.map {|key,value| "#{key}='#{value}'" }.join(' ')
49+
end
50+
51+
private
52+
53+
def method_missing(method, *args)
54+
@response.send(method.intern, *args)
55+
end
56+
end
57+
end
58+
end
59+
end

lib/jquery/fileupload/rails/upload.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
require "jquery/fileupload/rails/engine"
22
require "jquery/fileupload/rails/version"
3+
require "jquery/fileupload/rails/middleware"

vendor/assets/javascripts/jquery-fileupload/jquery.iframe-transport.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,13 @@
9696
.val(field.value)
9797
.appendTo(form);
9898
});
99+
// Add a hidden `X-Requested-With` field with the value `IFrame` to the
100+
// form, to help server-side code to determine that the upload happened
101+
// through this transport.
102+
$('<input type="hidden" />')
103+
.prop('name', 'X-Requested-With')
104+
.val('IFrame')
105+
.appendTo(form);
99106
}
100107
if (options.fileInput && options.fileInput.length &&
101108
options.type === 'POST') {

0 commit comments

Comments
 (0)