1 Refused to display ‘url’ in a frame because it set 'X-Frame-Options' to 'sameorigin' 怎么解決?


進在開發公司的文件中心組件,提供各個子系統的附件上傳下載、預覽、版本更新等功能,前端在今天突然給我發一張圖,說預覽縮略圖遇到問題了,然后發了個截圖給我:

這很明顯是一個跨域問題,

X-Frame-Options HTTP 響應頭是用來給瀏覽器指示允許一個頁面可否在 <frame>, <iframe>或者 <object> 中展現的標記。網站可以使用此功能,來確保自己網站的內容沒有被嵌到別人的網站中去,也從而避免了點擊劫持 (clickjacking) 的攻擊。

X-Frame-Options 有三個值:

DENY

  表示該頁面不允許在 frame 中展示,即便是在相同域名的頁面中嵌套也不允許。

SAMEORIGIN

  表示該頁面可以在相同域名頁面的 frame 中展示(一般默認是這種)。

ALLOW-FROM uri

  表示該頁面可以在指定來源的 frame 中展示。

此處很明顯需要在中間件里面修改一下響應頭的X-Frame-Options屬性,core的中間件流程如下:

所以我們需要實現一個響應頭的增刪集合類:

    /// <summary>
    /// 響應頭的增刪集合
    /// </summary>
    public class SecurityHeadersPolicy
    {
        public IDictionary<string, string> SetHeaders { get; }
             = new Dictionary<string, string>();

        public ISet<string> RemoveHeaders { get; }
            = new HashSet<string>();
    }

 

然后實現一個增刪響應頭的中間件:

/// <summary>
    /// 中間件實現
    /// </summary>
    public class SecurityHeadersMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly SecurityHeadersPolicy _policy;

        public SecurityHeadersMiddleware(RequestDelegate next, SecurityHeadersPolicy policy)
        {
            _next = next;
            _policy = policy;
        }

        public async Task Invoke(HttpContext context)
        {
            IHeaderDictionary headers = context.Response.Headers;

            foreach (var headerValuePair in _policy.SetHeaders)
            {
                headers[headerValuePair.Key] = headerValuePair.Value;
            }

            foreach (var header in _policy.RemoveHeaders)
            {
                headers.Remove(header);
            }

            await _next(context);
        }
    }

提供響應頭的增刪方法:

    /// <summary>
    /// 響應頭的增刪方法
    /// </summary>
    public class SecurityHeadersBuilder
    {
        private readonly SecurityHeadersPolicy _policy = new SecurityHeadersPolicy();
        public SecurityHeadersBuilder AddCustomHeader(string header, string value)
        {
            _policy.SetHeaders[header] = value;
            return this;
        }
        public SecurityHeadersBuilder RemoveHeader(string header)
        {
            _policy.RemoveHeaders.Add(header);
            return this;
        }
        public SecurityHeadersPolicy Build()
        {
            return _policy;
        }
    }

然后我們需要一個中間件的拓展方法:

    /// <summary>
    /// 中間件拓展方法
    /// </summary>
    public static class UseSecurityHeaders
    {
        public static IApplicationBuilder UseSecurityHeadersMiddleware(this IApplicationBuilder app, SecurityHeadersBuilder builder)
        {
            SecurityHeadersPolicy policy = builder.Build();
            return app.UseMiddleware<SecurityHeadersMiddleware>(policy);
        }
    }

然后就是在startup的Configure方法中注冊我們的中間件:

            //允許iframe嵌入資源
            app.UseSecurityHeadersMiddleware(new SecurityHeadersBuilder()
              .AddCustomHeader("X-Frame-Options", "AllowAll")
            );

我在這里使用的值是“AllowAll” 而不是“ALLOW-FROM uri” 是為了方便測試,如果開發的話應該是需要進行配置的,到這里再嵌入網頁即可成功。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM