如何在JavaScript中设置X-Frame-Options?附服务端配置指引
前端JavaScript代码完全无法设置X-Frame-Options响应头。
X-Frame-Options是服务端生成HTTP响应时携带的安全类响应头,浏览器接收到响应后会根据这个字段的值,判断当前页面是否允许被iframe、frame等标签嵌入,这个校验逻辑是浏览器底层实现的,前端页面既没有权限修改任意站点(包括自身站点、第三方站点)返回的响应头,也无法绕过这个安全校验。
你嵌入YouTube视频遇到X-frame-options was set to sameorigin报错,本质是你请求的YouTube资源路径本身在服务端配置了禁止跨站嵌入的规则,你的站点前端代码没有任何办法修改YouTube服务端返回的响应头,这类问题首先要排查是不是用错了第三方平台的嵌入地址:YouTube普通的视频观看页(路径格式为/watch?v=视频ID)默认就设置了SAMEORIGIN禁止跨站嵌入,官方允许嵌入的地址格式为https://www.youtube.com/embed/视频ID,替换成这个格式的地址就能解决绝大多数YouTube嵌入拦截问题。
X-Frame-Options支持3种配置值,按需选择即可:
DENY:完全禁止页面被任何站点嵌入,即便是同域名下的页面嵌套也不允许SAMEORIGIN:仅允许同域名下的页面嵌套当前页面ALLOW-FROM 具体URI:仅允许指定来源的站点嵌套当前页面(注意部分老旧浏览器不兼容该值,现代站点更推荐搭配CSP的frame-ancestors指令做更灵活的来源控制)
不同服务端/托管环境的配置方式如下:
Nginx
在站点对应的server或location配置块中添加配置行:
# 把引号内的值替换为你需要的配置项 add_header X-Frame-Options "SAMEORIGIN" always;
配置完成后执行nginx -s reload重载配置即可生效。
Apache
可以在站点根目录的.htaccess文件,或者Apache的主站点配置文件中添加:
# 替换为你需要的配置值 Header always set X-Frame-Options "SAMEORIGIN"
修改完成后重启Apache服务生效。
原生Node.js HTTP服务
在处理请求的逻辑中,给响应对象设置对应头即可:
const http = require('http'); const server = http.createServer((req, res) => { // 设置X-Frame-Options头 res.setHeader('X-Frame-Options', 'SAMEORIGIN'); // 其余业务响应逻辑 res.end('page content'); }); server.listen(3000);
Express框架服务
可以通过全局中间件统一给所有响应添加头:
const express = require('express'); const app = express(); // 全局配置响应头 app.use((req, res, next) => { res.setHeader('X-Frame-Options', 'SAMEORIGIN'); next(); }); // 其余路由、业务逻辑 app.listen(3000);
如果你的项目接入了helmet安全中间件,它默认就会将X-Frame-Options设置为SAMEORIGIN,无需额外手动配置。
静态站点托管平台(Vercel、Netlify、云厂商对象存储托管等)
这类平台不需要改服务端逻辑,通过平台规定的配置文件设置响应头规则即可。以Netlify的netlify.toml配置为例:
[[headers]] for = "/*" # 匹配所有路径 [headers.values] X-Frame-Options = "SAMEORIGIN"
Vercel、阿里云OSS、腾讯云COS等平台的配置逻辑类似,按照平台官方的响应头配置规则填写对应值即可。
注意:所有针对X-Frame-Options的配置,仅对你自己持有服务端控制权的域名生效,嵌入第三方站点内容遇到的X-Frame-Options拦截,无法通过修改你自己站点的配置解决,必须使用第三方官方开放的、允许嵌入的资源地址。
内容的提问来源于stack exchange,提问作者aplua

