You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Safari 15-16.3中实现仅允许iframe嵌入访问网页的限制?

针对Safari 15-16.3的替代实现方案

要实现阻止直接URL访问、允许iframe嵌入的需求,在不支持Sec-Fetch-Site的Safari版本中,可以通过服务器端Referer头校验结合前端上下文检查的方式实现,双重保障可靠性:

1. 服务器端(Next.js)校验Referer头

直接访问时,Referer请求头通常为空(或仅包含当前站点域名);而页面被iframe嵌入时,Referer会携带父页面的域名信息。你可以在Next.js的中间件或页面的getServerSideProps中添加以下逻辑:

// 示例:Next.js 中间件 middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';

export function middleware(request: NextRequest) {
  const referer = request.headers.get('referer');
  const currentHost = request.headers.get('host');

  // 无Referer大概率是直接访问,拦截
  if (!referer) {
    return NextResponse.redirect(new URL('/blocked', request.url));
  }

  const refererHost = new URL(referer).host;
  // 跨域Referer说明是跨域iframe嵌入,允许访问
  if (refererHost !== currentHost) {
    return NextResponse.next();
  }

  // 同域来源,可能是同域跳转或同域iframe,允许请求但交由前端进一步验证
  return NextResponse.next();
}

// 指定需要拦截的页面路径
export const config = {
  matcher: '/your-protected-page/:path*',
};

2. 前端页面上下文检查

对于同域嵌入或服务器端无法准确判断的场景,在页面加载时通过JS检查当前页面是否处于iframe中:

// 在受保护的页面组件中添加
import { useEffect } from 'react';

export default function ProtectedPage() {
  useEffect(() => {
    if (window.top === window.self) {
      // 不在iframe中,判定为直接访问,跳转至拦截页面
      window.location.href = '/blocked';
    }
  }, []);

  return <div>仅允许iframe嵌入访问的内容</div>;
}

这种方式可以覆盖同域iframe嵌入的场景,同时补充服务器端校验的不足(服务器端无法区分同域跳转和同域iframe)。

注意事项

  • Referer头可能在隐私模式下被浏览器隐藏,此时服务器端会误判为直接访问,前端检查可作为兜底方案。
  • 前端检查可被禁用JS绕过,但结合服务器端校验能覆盖绝大多数正常场景。
  • 若仅允许特定域名的iframe嵌入,可在服务器端进一步校验Referer的域名是否在白名单内,提升安全性。

内容的提问来源于stack exchange,提问作者Ivan Banha

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.23 17:42:22