问题
I develop a web app with rails 3.2, turbolinks and Filepicker.io
I loade the API key like this (coffeescript). I think $(document).ready
is enough, as the filepicker script get loaded once on the first request.
$(document).ready ->
filepicker.setKey "MY_KEY"
I load Filepicker with the following (coffeescript).
I should note that I use the jquery-turbolinks
gem, which builds the support for turbolinks right into jquery.
jQuery ->
$("#publications_bulk-new #upload-button").on "click", ->
form = $(this).closest('form')
filepicker.pickAndStore
When I visit the page directly, filepicker works as expected. However, when I visit the page using a turbolink request I cant upload any file.
I can open the form, browse in Dropbox etc. But When Uploading, I see the following error message in red:
Cannot send results to the applicaiton. Sorry about this, it's our fault. Please close this window and try again.
Trying again does not help.
I checked the console of Chrome 28.0 for any error messages and found this:
Blocked a frame with origin "https://www.filepicker.io" from accessing a frame with origin "http://placeholder.library.dev". The frame requesting access has a protocol of "https", the frame being accessed has a protocol of "http". Protocols must match.
main.js:7
u main.js:7
l main.js:7
i.uploadFiles main.js:7
v.onFileDrop main.js:7
r lodash.min.js:6
(anonymous function) main.js:7
Uncaught Communication iframe not found main.js:7
u main.js:7
l main.js:7
i.uploadFiles main.js:7
v.onFileDrop main.js:7
r lodash.min.js:6
(anonymous function)
Update 2013-07-29 "Protocols, domains, and ports must match"
I pushed the current code to my production environment, as the message suggests this depends on the missing SSL encryption of my (development) page.
Unfortunately, this is not the only problem
Blocked a frame with origin "https://www.filepicker.io" from accessing a frame with origin "https://jkreutz.mylibrar.io". Protocols, domains, and ports must match. main.js:7
u main.js:7
l main.js:7
i.uploadFiles main.js:7
v.onFileDrop main.js:7
r lodash.min.js:6
(anonymous function) main.js:7
Uncaught Communication iframe not found main.js:7
u main.js:7
l main.js:7
i.uploadFiles main.js:7
v.onFileDrop main.js:7
r lodash.min.js:6
(anonymous function)
回答1:
TL;DR - Workaround: Use traditional javascript file inclusion in the body, and be careful about when you call filepicker.setKey(...)
.
I'm working with a Rails 4 app with Turbolinks enabled, and I'm encountering similar problems with Filepicker when the page containing the filepicker is loaded a second (or more) time via turbolinks. I've tried both traditional and async js, and each has its own way of breaking.
When using the "advanced" (async js) method, the failure is the nasty message:
Cannot send results to the application. Sorry about this, it's our fault. Please close this window and try again.
And javascript console errors of Blocked a frame with origin ...
and Uncaught Communication iframe not found
(in Chrome).
I'm pretty sure this is caused by the iframe that gets added to the body by the js when it is first loaded being clobbered when the page body is changed (by turbolinks) and never added again on the second turbolinks page load.
With the traditional js approach, the order of things is very finicky. If I just have the traditional js included on the page, and then the filepicker.setKey(...)
afterwards on the page, the second page load results in Uncaught FilepickerException: API Key not found
. However, if I'm sure to call .setKey()
later on (like when the picker is invoked), it seems to work. (The communication iframe appears to be created again on the page with the traditional js method.)
I've written to the Filepicker support about this, and hopefully the come out with a recommended / documented approach for this (as they appear to be keen on rails...).
回答2:
I could not get stevo's answer to work. I thought that maybe using data-turbolinks-permanent
on the communication iframe would work, but alas Turbolinks expects the incoming page body to also have said iframe elements.
The solution we ended up using was this:
// Filepicker.js does not play well with Turbolinks. It needs a communication
// iframe loaded on every page load. Unfortunately there is no accessible API for
// removing Filepicker's iframes. This solution copies the iframes over to the
// incoming body for filepicker to continue using on each new page request.
document.addEventListener("turbolinks:before-render", function(event) {
event.data.newBody.appendChild(document.querySelector('#filepicker_comm_iframe'));
event.data.newBody.appendChild(document.querySelector('#fpapi_comm_iframe'));
});
来源:https://stackoverflow.com/questions/17762697/how-to-get-filepicker-and-turbolinks-to-play-well-together