跳到正文
runningbai
Powered by Pagefind
独立项目

Adsterra 300×250 实战:从页面劫持到 iframe、Referer 和 CPM 恢复

记录 Warhounds 接入 Adsterra 300×250 Banner 后遇到的移动端页面跳转、iframe 隔离、Cloudflare 308、Referer 与 CPM 异常,以及最终稳定方案。

2026/9/4阿白最后更新: 2026/9/415 分钟阅读

最近给 Warhounds 做广告变现实验时,我原本以为接一个 300×250 Banner 只是把 Adsterra 后台的 GET CODE 贴进页面。

结果这个小广告位前后改了好几版,踩到了几个很典型的问题:

  • 广告能正常展示,但某个移动端 creative 会直接把当前 Warhounds 页面跳到广告主页面;
  • 加 sandbox 后安全了,但 Referer / Origin 又发生变化;
  • 把广告执行页放到 ads.warhounds.org 后,后台有 impressions,却一度没有 CPM;
  • Cloudflare Pages 会把 .html 自动 308 到无扩展名 URL,导致 _headers 规则看起来写对了、实际却没命中;
  • 广告放在文章标题下面虽然曝光高,但手机首屏体验很差。

现在这套方案已经稳定运行了一段时间。这篇只记录真实踩坑和最终做法,不讨论“广告位越多越赚钱”这种泛泛建议。

最开始:直接使用 Adsterra 官方 Banner 代码

最初的 300×250 就是 Adsterra Publisher Dashboard 给出的标准代码,结构类似:

<script>
  atOptions = {
    'key': 'YOUR_KEY',
    'format': 'iframe',
    'height': 250,
    'width': 300,
    'params': {}
  };
</script>
<script
  src="https://www.highrevenueformat.com/YOUR_KEY/invoke.js"
></script>

这一版最大的优点是简单,而且一开始展示、统计、计费都正常。

问题出在手机端。我实际遇到过某个广告 creative 不是正常新开落地页,而是把 Warhounds 当前顶层页面直接替换成广告主页面

这就不是普通的“广告有点烦”了,而是会直接破坏网站体验。

还有一个容易混淆的地方:

format: 'iframe'

只是 Adsterra Banner 自己的广告格式,不代表 Publisher 页面已经获得了浏览器 sandbox 隔离。

也就是说,官方代码直接在主页面执行时,invoke.js 本身仍然运行在当前页面上下文里。

第一版保护:给广告再套一层 sandbox iframe

为了阻止第三方广告导航顶层页面,我把结构改成:

Warhounds 文章页
└─ sandbox iframe
   └─ 独立广告执行页
      └─ Adsterra 官方 Banner

外层 iframe 最终只保留这几个权限:

sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"

允许:

allow-scripts
allow-same-origin
allow-popups
allow-popups-to-escape-sandbox

明确不加:

allow-top-navigation
allow-top-navigation-by-user-activation
allow-modals
allow-downloads

正常广告点击仍然可以打开新 tab / window,但不给广告顶层导航权限。

这里还有一个之前踩过的坑:不要简单去掉 allow-same-origin

早期我试过只给:

allow-scripts allow-popups allow-popups-to-escape-sandbox

这样 iframe 会进入 opaque origin,后续第三方请求的来源上下文会变得很难看,Referer / 来源识别也更容易出问题。

所以后来保留了 allow-same-origin,同时把广告执行页放到另一个 Origin。

第二版:ads.warhounds.org 跨域隔离

当时的结构是:

https://warhounds.org

https://ads.warhounds.org/adsterra/300x250

Adsterra invoke.js

这样 allow-scripts + allow-same-origin 的同时,广告执行页仍然和主站是不同 Origin,浏览器安全边界更清晰。

同时 iframe 使用:

referrerpolicy="strict-origin-when-cross-origin"

广告执行页里加:

<meta name="referrer" content="origin" />

从安全设计看,这一版是我最满意的。

但是上线后又遇到了两个现实问题。

Cloudflare Pages 的一个坑:.html 会被 308

最初 iframe 地址写的是:

https://ads.warhounds.org/adsterra/300x250.html

Cloudflare Pages 实际会把它 308 到:

https://ads.warhounds.org/adsterra/300x250

而我的 _headers 一开始只匹配了 .html 地址。

结果就是:

  1. 第一个 .html 请求命中了允许 iframe 的规则;
  2. Cloudflare 308 到无扩展名 URL;
  3. 最终 200 响应重新继承全局 X-Frame-Options: SAMEORIGIN
  4. 手机端直接显示 ads.warhounds.org 拒绝连接。

修复方式很简单:iframe src 和 _headers 都直接使用 Cloudflare 最终 URL,不要依赖中间跳转。

例如:

/adsterra/300x250

这个坑非常隐蔽,因为源码和第一跳响应头看起来都可能是对的,必须检查最终 200 Response Headers。

广告能展示,不代表计费一定正常

跨域版稳定展示后,我又观察到一个异常:

Adsterra 后台已经出现新的 impressions,但这批流量一度是:

Impressions > 0
CPM = $0
Revenue = $0

这时我没有继续加广告位,也没有乱改 key,而是只改一个变量:广告执行页的来源

把:

ads.warhounds.org

改回:

warhounds.org

最终结构变成:

https://warhounds.org/文章

/adsterra/300x250

Adsterra invoke.js

浏览器里实际抓到的 vendor 请求 Referer 也从:

https://ads.warhounds.org/

变成:

https://warhounds.org/

随后 Adsterra 后台重新开始出现非 0 CPM,后续运行也稳定下来。

这里我不会下结论说“Adsterra 一定不支持子域”。我的样本只是一个真实站点的一次实验,能确定的是:

对 Warhounds 这个 Placement 来说,广告执行 Origin 确实是一个会影响实际 monetization 结果的重要变量。

以后再遇到“广告能显示、后台也有 impression、但 CPM 长时间为 0”,我会第一时间检查实际 Referer 和广告执行 Origin,而不是只盯前端是否渲染成功。

目前 Warhounds 的 300×250 结构

现在文章页使用同源 iframe:

<iframe
  src="/adsterra/300x250"
  width="300"
  height="250"
  sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
  referrerpolicy="strict-origin-when-cross-origin"
  loading="lazy"
></iframe>

广告执行页继续使用 Dashboard 当前给出的官方 Banner 代码,不去改它内部的:

format: 'iframe'
height: 250
width: 300
params: {}

并保留:

<meta name="referrer" content="origin" />

如果是 Cloudflare Pages,广告执行页额外设置:

X-Robots-Tag: noindex, nofollow
Content-Security-Policy: frame-ancestors https://warhounds.org

因为现在 iframe 与主站同源,所以全站原本的:

X-Frame-Options: SAMEORIGIN

也可以正常工作。

这不是一个完美的安全边界

这里必须单独说明。

当前方案是:

同源 iframe
+ allow-scripts
+ allow-same-origin

它的隔离强度 弱于之前的 ads.warhounds.org 跨 Origin 方案

所以我把它理解成一个经过实际收入验证的工程折中,而不是“绝对安全”的通用广告沙箱。

另外,我后来在 Adsterra Publisher 条款里还看到一条非常重要的限制:Publisher 未经 Adsterra 事先书面同意,不允许把 Adsterra Ad Tag 放到 iframe 里。

因此这套实现如果要复制到其他站点,应该先检查你当前账户的最新条款,并向广告平台确认是否允许这种结构。技术上能跑,不代表合同上自动允许。

广告位置也改了:不要挡住用户第一答案

除了安全和计费,这次还顺便改了广告位置。

一开始 300×250 是:

文章标题
摘要
更新时间

300×250

正文

桌面端还能接受,手机端就很明显:用户从 Google 进来还没看到攻略内容,先占掉一大块屏幕展示广告。

现在改成:

标题 / 摘要

正文第一小节(大多数文章是 Quick Answer)

300×250

第二小节及后续内容

而且:

  • 一篇文章只放 1 个 300×250;
  • loading="lazy"
  • 不恢复文章 footer 的第二个相同 Placement;
  • Native、728×90、320×50 Sticky 暂时都不加。

因为 Warhounds 同时还在申请 Google AdSense,这个阶段我宁愿广告少一点,也不想为了短期曝光把页面做得像广告站。

如果你也遇到类似问题,可以直接把这段丢给 AI

如果不想自己研究整套过程,直接把下面要求交给 Codex、Claude Code 或其他能改仓库的 Agent:

请把文章页第三方 300×250 Banner 改成单独的同源 sandbox iframe。

目标:
主站文章页
→ /adsterra/300x250
→ 广告平台官方 Banner GET CODE

要求:
1. 主文章页不要直接执行第三方 invoke.js。
2. iframe 使用:
   sandbox="allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"
3. 禁止加入任何 allow-top-navigation*。
4. iframe 使用 referrerpolicy="strict-origin-when-cross-origin" 和 loading="lazy"。
5. 广告执行页设置 <meta name="referrer" content="origin">。
6. 广告执行页内部保持广告平台官方 key、format、width、height、params 和 invoke.js URL 不变。
7. Cloudflare Pages 直接使用最终无扩展名 URL,不要依赖 .html → 308。
8. 一篇文章只保留一个 Placement,位置放在正文第一小节结束后、第二个 H2 前。
9. 检查最终 HTML、Response Headers 和广告 vendor 请求 Referer。
10. 不要顺手增加 Native、Sticky 或其它广告位。
11. 保留 master switch,只有精确 true 才输出广告。
12. 修改前确认广告平台当前条款是否允许 Publisher 把 Ad Tag 放入 iframe。

修改后运行 lint、typecheck、test、production build,并检查最终 dist HTML。

这基本就是这次 Warhounds 实验最后沉淀下来的实现要求。

这次最值得记住的几条经验

最后把这次来回折腾浓缩一下:

  1. 广告能显示,不代表接入就是正确的。 还要看主页面是否会被劫持、后台有没有 CPM 和 Revenue。
  2. 平台自己的 format: iframe 不等于浏览器 sandbox。 两者不是同一层。
  3. 没有 allow-same-origin 的 sandbox 会变成 opaque origin。 Referer / 来源识别可能随之变化。
  4. 跨 Origin 更安全,但广告网络不一定按你预期识别来源。 必须看真实后台数据。
  5. 一次只改一个变量。 这次能发现 Origin 和 CPM 的关联,就是因为没有同时换 key、位置和格式。
  6. Cloudflare Pages 要检查最终 URL。 .html 的 308 足够让一条正确的 _headers 规则彻底失效。
  7. Network Referer 比“页面看起来正常”更有价值。 最后要看第三方脚本实际收到什么来源。
  8. 不要主动刷 impression 或 click。 用自然流量看数据,避免把测试本身变成异常流量。
  9. 移动端第一屏先给答案,再给广告。 对攻略站尤其重要。
  10. 广告平台条款优先于技术实现。 如果 iframe 需要书面许可,就先拿许可。

这次最大的感受是,第三方广告其实是一个“运行别人 JavaScript + 还要让统计平台正确识别流量”的系统问题,不只是前端页面里多一段 <script>

对独立站来说,收益重要,但页面控制权更重要。至少现在 Warhounds 的 300×250 已经从“能展示”变成了“展示、位置、Referer、统计和回滚都可控”。

相关文章

这篇文章有帮助吗?