ASP.NET MVC Script Bundle在HTTPS环境下无法渲染及混合内容错误
这问题我之前部署HTTPS站点时碰到过,本质是浏览器的混合内容安全策略在起作用——你的页面通过HTTPS加载,但请求的样式表用了http://domain:443/Content/css/mycss.css,这种HTTP协议加HTTPS默认端口的组合完全不符合规范,浏览器直接就给拦截了。
下面是几个针对性的解决办法:
修正Bundle的URL生成逻辑,避免硬编码协议
别在代码里手动写死http://协议,改用框架自带的URL生成方法,它们会自动匹配当前页面的请求协议。比如在ASP.NET中:- 用
@Styles.Render("~/Content/css")来渲染样式Bundle,而不是自己拼接URL - 或者用
Url.Content("~/Content/css/mycss.css"),它会根据当前请求的协议(HTTPS)生成对应的资源地址
- 用
配置反向代理/服务器传递正确的协议头
如果你的应用前面有Nginx、IIS这类代理服务器,很可能是代理没把用户实际使用的HTTPS协议传递给应用,导致应用误以为是HTTP请求,进而生成了错误的http://domain:443地址:- Nginx里要添加:
proxy_set_header X-Forwarded-Proto $scheme; - IIS可以在ARR(应用程序请求路由)里开启“转发HTTP头”,确保
X-Forwarded-Proto被正确传递
- Nginx里要添加:
强制所有资源使用HTTPS(兜底方案)
如果你确定站点只会在HTTPS环境下运行,可以直接在Bundle配置里指定HTTPS协议。比如在BundleConfig.cs中:bundles.Add(new StyleBundle("~/Content/css").Include( new Uri("https://domain/Content/css/mycss.css", UriKind.Absolute).ToString() ));不过这种方法不够灵活,优先推荐前两种自动适配的方式。
验证修复结果
修复后打开浏览器开发者工具(F12),切换到「Elements」标签,找到对应的<link>标签,确认生成的地址是https://domain/Content/css/mycss.css(不需要加443端口,HTTPS默认就用这个端口,浏览器会自动处理)。
为什么会出现http://domain:443这种奇怪的地址?大概率是应用内部获取到的请求协议是HTTP,但端口被设置成了443(可能是代理转发时的端口映射导致),两者拼接就产生了这个不符合规范的URL。
内容的提问来源于stack exchange,提问作者June

