X_FRAME_OPTIONS = 'SAMEORIGIN'作用及Django跨域iframe加载疑问
我用Django开发了一个站点并部署在Heroku平台,想在本地localhost的HTML页面的iframe中加载这个站点,但因为X_FRAME_OPTIONS默认值为DENY而无法实现。查资料知道要改成SAMEORIGIN,看到Django官方文档的说明:
Modern browsers respect the X-Frame-Options HTTP header which indicates whether a resource is allowed to load inside a frame or iframe. If the response contains the header with a value of SAMEORIGIN then the browser will only load the resource in a frame if the request comes from the same site.
我有两个疑问:
- 这里的「同站点」指的是部署该站点的本地电脑上的页面,还是已部署站点内的页面?
- 未部署的本地页面能不能通过设置这个Header加载已部署的站点?
关于「同站点」的定义
这里的「同站点」指的是你部署在Heroku上的那个线上站点本身,也就是只有该站点内部的页面(比如https://your-heroku-app.com/page1)才能用iframe加载这个站点的内容,和本地电脑没有关系。
浏览器判断「同站点」的核心是URL的协议、域名、端口三者完全一致:你的Heroku站点是线上域名(比如https://xxx.herokuapp.com),而本地localhost页面是http://localhost:xxxx,协议、域名、端口都不匹配,显然不属于同站点范畴。
本地页面能否通过设置该Header加载线上站点?
不行。SAMEORIGIN的限制是针对被嵌入的目标站点(也就是你的Heroku站点)设置的,它只允许和自己同站点的页面来嵌入。本地localhost页面和Heroku站点不属于同站点,哪怕你把Heroku站点的X_FRAME_OPTIONS改成SAMEORIGIN,本地页面还是没法嵌入它。
如果想要本地页面能嵌入这个线上站点,更推荐用Content-Security-Policy的frame-ancestors指令直接指定允许嵌入的源,步骤如下:
- 在Django的
settings.py中配置:
CONTENT_SECURITY_POLICY = { "frame-ancestors": ["http://localhost:8000"] # 替换成你的本地页面实际地址 }
- 同时把
X_FRAME_OPTIONS设置为None(Django 3.0+支持),避免和frame-ancestors规则冲突:
X_FRAME_OPTIONS = None
内容的提问来源于stack exchange,提问作者gks

