来自iframe的事件触发

时间:2014-05-07 16:00:16

标签: javascript jquery ruby-on-rails iframe

我正在将第三方照片上传服务与我的应用集成。所以我通过iframe将它加载到我的页面中。

上传服务完成上传我的照片后,它可以触发某个事件到我的父页面,即:

parent.$('body').trigger('photoUpload.complete');

或它在父页面中触发一个函数,即:

window.parent.reloadParentPage();

无论如何,我在Chrome控制台中收到此警告:

Uncaught SecurityError: Blocked a frame with origin "https://photoupload.com" from accessing a frame with origin "https://website.com".

我意识到这是一个安全问题,如下所述:

http://www.w3.org/TR/2008/WD-access-control-20080912/

所以我想启用原始https://photoupload.com来访问我的网站。我在我的控制器中做到了这一点:

after_filter :set_access_control_headers

然后方法:

def set_access_control_headers 
  headers['Access-Control-Allow-Origin'] = "https://photoupload.com" 
  headers['Access-Control-Request-Method'] = '*' 
end

请注意,https://photoupload.com是照片上传服务,https://website.com是我的网站。 (例如清酒的虚构名称),但它们都托管在heroku上。

如何使这项工作?

看到人们用这个成功的类似问题:

Triggering a jQuery event from iframe

更新

也许更好的问题是,我应该在哪个应用中设置标头?我在我的应用程序中假设?

更新II

有更好的方法吗?将iframe中的action / event / something发送到父页面,因此父页面可以以某种方式做出反应

2 个答案:

答案 0 :(得分:8)

只要您不必支持IE6或IE7,在iframe及其父级之间发送跨域消息的首选方法是使用window.postMessage(...)

由于你有能力修改上传服务,你应该让它调用这样的东西:

window.parent.postMessage('photoUpload.complete', 'https://website.com');

(第二个参数可以设置为'*',以允许iframe发送消息而不管包含页面的域名,但相应地安全性较低 - 在您的情况下可能不相关,但因为没有实际数据发送)。

并且您的网站会使用类似

的内容
if (!window.addEventListener) {
    // IE8 support (could also use an addEventListener shim)
    window.attachEvent('onmessage', handleMessage);
} else {
    window.addEventListener('message', handleMessage, false);
}

function handleMessage(event) {
  // check where the message is coming from - may be overkill in your case
  if (event.origin==='https://photoupload.org') {
    // check event type - again probably not required
    if (event.data==='photoUpload.complete') {
      // do your thing
    }
  }
}

如果您想将邮件从外部页面发回iframe,它的设置基本相同,但您发送的内容为:

iframe.contentWindow.postMessage(...)

如果需要IE7或IE6支持,则不支持postMessage(),但您可以使用http://easyxdm.net/wp/

之类的内容

答案 1 :(得分:0)

我想这条线也应该工作

window.parent.$(window.parent.document).trigger('photoUpload.complete');

说明:在您的代码父级中.$('body').trigger('photoUpload.complete'); “ body”是指iframe主体,而不是父窗口主体。