How to get filepicker and turbolinks to play well together?

六眼飞鱼酱① 提交于 2019-12-09 07:33:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!