我曾经问过这个
question,发现IE阻止了iframe中的跨域cookie,除非你设置了一个
p3p policy.到目前为止,p3p修复在ie中工作得很好.但是,现在我们在safari中遇到了同样的错误.
我发现一篇有不同的p3p policy的文章用于野生动物园.我添加了这个代码来设置p3p策略,但是我仍然收到请求验证令牌错误.
public static void SetP3PCompactPolicy() { HttpContext current = HttpContext.Current; if (current.Request.UserAgent.ToLower().IndexOf("safari") >= 0) HttpContext.Current.Response.AddHeader("p3p","CP=\"IDC DSP COR CURa ADMa OUR IND PHY ONL COM STA\""); else HttpContext.Current.Response.AddHeader("p3p","CP=\"IDC DSP COR ADM DEVi TAIi PSA PSD IVAi IVDi CONi HIS OUR IND CNT\""); }
我不知道这是什么意思,但它不适用于Safari(5).
另外,当我收到服务器错误时,所有的信息都会发送到我的报告中,包括所有的HTTP标头.在这些错误中,p3p头不会出现.我不知道这是否是设计的,或者是否是问题的指标.
解决方法
问题是Safari不允许将cookie设置在iframe中,除非用户与该iframe进行交互.对于某些,这意味着点击链接.我找到一个更好的解决方案是做一个重定向.
首先,我把这个表格放在我的网页上.其实我把它放在了在iframe中提供的每个视图使用的母版页中.
<% if(SecurityHelper.BrowserIsSafari) { %> <% using (Html.BeginForm("SafariRedirect","Framed",FormMethod.Post,new { id="safari-fix-form" })) { %> <%: Html.Hidden("safariRedirectUrl")%> <% } %> <% } %>
因为我只希望在用户使用safari时工作,所以我在静态帮助器类中创建了这个属性来检查用户名
public static bool BrowserIsSafari { get { return HttpContext.Current.Request.UserAgent.ToLower().IndexOf("safari") >= 0; } }
然后,在我的控制器中,我有以下操作
[HttpPost] public ActionResult SafariRedirect(string safariRedirectUrl) { Response.Cookies.Add(new HttpCookie("safari_cookie_fix","cookie ok")); return Redirect(safariRedirectUrl); }
在我的主页中,在标题中,我的脚本在同样的if语句中声明,该语句确定表单是否被呈现.在我的脚本文件中,我有这个jquery
$(function () { if ($.browser.safari == true && document.cookie.indexOf("safari_cookie_fix") == -1) { var url = location.href; $('#safariRedirectUrl').val(url); $('#safari-fix-form').submit(); } });
iframe第一次加载一个页面,如果它是safari,并且没有设置cookie,则会发布表单,设置cookie,并将用户重定向回同一个url.