Rail, ajax and iframe in Safari

╄→гoц情女王★ 提交于 2020-01-02 11:23:58

问题


In our application we have some elements that work with ajax. We offer users to embed parts of the app in an iframe.

Everything work fine in Chrome and Mozilla. In Safari we get 422 error, and the server log looks like this:

2015-07-15T08:26:06.818885+00:00 app[web.1]: Completed 422 Unprocessable Entity in 4ms
2015-07-15T08:26:06.815411+00:00 app[web.1]: Can't verify CSRF token authenticity
2015-07-15T08:26:06.823389+00:00 app[web.1]: ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

We figured out that if we access directly the iframe url AND THEN to the page which contains the iframe it works fine, which might indicates that it has to do with cookies.

I tried this solution, but we still have this problem.


回答1:


Finally I figured out that Safari does not allow keeping cookies in iframe.

It means that if you need to use cookies, you need to do something.

The solution I found is this:

  1. In the iframe code check if session[:safari_cookie_fixed] exist. If not, render a code that will communicate using postMessage with the parent window and let him know that we need a redirection.
  2. The parent window send a signal via postMessage to the iframe when the iframe is loaded. The listener, which was rendered in case the cookie does not exist, send a signal to the parent to perform redirect, and the parent does a redirection to /set-cookie page in the iframe domain, adding its current url as a query-string parameter.
  3. set_cookie action save a cookie safari_cookie_fixed and redirect back to the parent page (which its url is available in the query-string)

Of-course this solution requires adding some js code in the parent page, but when you give your user the iframe html code you can include the js as well.




回答2:


Safari does not (by default) allow cookies to be set in iFrames unless the user has visited the site already. Imagine this code:

# a.com
<iframe src="b.com/iframe">

If you visit b.com directly (any page) and it sets a cookie, then Safari will send that cookie when you visit a.com and the iFrame to b.com is loaded.

However, if you visit a.com without first visiting b.com, then Safari will ignore any cookie that b.com/iframe tries to set.

The solution is described here in the section called "A solution for Safari".

  1. Detect if cookies are supported.
  2. If not, put an overlay on the page saying, "This site requires cookies. Please click here to continue."
  3. When the user clicks on the link/button, open a popup, which sets a cookie and closes itself. On desktops you can make the popup fairly small and innocuous. On mobile devices it is uglier since you can't make the popup smaller than full-screen. However, either way the popup is only on screen for less than a second.
  4. The iframe reloads itself and it can now use cookies.


来源:https://stackoverflow.com/questions/31429589/rail-ajax-and-iframe-in-safari

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