我有一个非常基本的 ASP.NET MVC 5应用程序,托管在Intranet服务器上,其中一个页面具有显示文档的iframe
:
<div class="document-view-container">
...
<iframe class="document-frame" src="@Url.Action("GetDocumentImage", "Imaging", ...)" ></iframe>
...
</div>
返回的文档有时是用作application/pdf
的PDF,有时是作为text/plain
的一段文本,有时是用作text/xml
的XML。
GetDocumentImage
方法从数据库中检索文档内容,并使用File
返回它:
return File(doc.document.ToArray(), doc.mime_type);
当文档恰好是 XML 时,它通常包含对样式表的引用,应使用该样式表查看它:
<?xml-stylesheet type="text/xsl" href="//server.local/folder/content/grn.xslt"?>
<document>
...
</document>
有时该样式表来自与@Url.Action()
返回的相同的子域(即与iframe
相同的来源(,但有时它不是。
如果没有,样式表已成功加载并在Firefox 中使用,但 Chrome 拒绝加载样式表并在控制台中显示错误,
不安全的尝试从带有 URL
http://documents.server/imaging/GetDocumentImage/52855
的框架加载 URLhttp://server.local/folder/content/grn.xslt
。域、协议和端口必须匹配。
这是一个已知问题,但我的理解是它仅适用于本地文件,不适用于从服务器提供的文件,其中一个解决方案是专门在服务器上托管文件。此外,它可以在火狐中工作。
这个问题的根源是什么?
- 是 Chrome 将
iframe
中的 XML 视为本地文件,因此错误地阻止它从服务器请求样式表吗? - 是Firefox,它有一个安全问题,它允许来自
iframe
的XML文件在应该被禁止的时候请求样式表? - 是我,谁没有从服务器正确提供XML,使Chrome将其误认为本地文件?
修复它的正确方法是什么?
我认为有不同的策略,在Firefox中,您可以请求样式表,因为Firefox在基于xml-stylesheet
的请求上使用CORS(https://www.w3.org/wiki/CORS#xml-stylesheet_processing_instruction_.28XMLSS.29(,而Chrome不会对此类请求应用CORSs,Safari/Webkit(https://bugs.webkit.org/show_bug.cgi?id=110880 也没有(。
因此,后者阻止尝试,前者仅满足它,因为它对请求使用 CORS,并且您在 http://documents.server/上的应用程序设置为允许通过回答access-control-allow-origin: *
向任何人发出请求。如果 http://documents.server/不这样做,那么即使在 Firefox 中,跨源加载也会失败。