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

如何在Django中按需渲染移动端与桌面端广告以避免JS冲突?

解决Cloudflare缓存下Django项目按需加载广告脚本的方案

方案1:客户端动态加载(纯前端实现,无服务器依赖)

核心是先判断设备类型,再动态创建并插入对应广告的脚本和元素,从根源避免加载不必要的脚本。

  1. 先写设备检测逻辑:
// 简单的设备判断,可根据需求调整阈值
function isMobile() {
    return /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) || 
           (window.innerWidth <= 768);
}
  1. 动态生成广告模块:
<!-- 先留一个空容器 -->
<div id="ad-container"></div>

<script>
document.addEventListener('DOMContentLoaded', function() {
    const container = document.getElementById('ad-container');
    const isMobileDevice = isMobile();

    // 创建广告外层容器
    const adWrapper = document.createElement('div');
    adWrapper.className = isMobileDevice ? 'ads-mobile' : 'ads-desktop';

    // 创建广告占位元素
    const adIns = document.createElement('ins');
    adIns.className = 'ee31';
    adIns.dataset.zoneid = '68';
    adWrapper.appendChild(adIns);

    // 加载对应广告脚本
    const adScript = document.createElement('script');
    adScript.async = true;
    adScript.type = 'application/javascript';
    adScript.src = isMobileDevice ? 'https://cdn-ads.com/ad-mobile.js' : 'https://cdn-ads.com/ad-desktop.js';
    adWrapper.appendChild(adScript);

    // 执行广告初始化逻辑
    const initScript = document.createElement('script');
    initScript.textContent = '(Ads = window.Ads || []).push({"goserve": {}});';
    adWrapper.appendChild(initScript);

    // 把广告模块插入页面
    container.appendChild(adWrapper);
});
</script>

这个方案完全在用户浏览器端执行,不受Cloudflare缓存影响,每个用户只会加载自己设备对应的脚本。

方案2:Cloudflare边缘检测+分设备缓存(高效推荐)

利用Cloudflare的设备检测能力,在边缘层直接返回对应设备的页面,同时配置分设备缓存,避免缓存冲突。

步骤1:开启Cloudflare设备检测

在Cloudflare控制台的「规则 > 设备检测」中开启功能,开启后Cloudflare会给源站发送CF-Device-Type请求头(值为mobile/desktop),并且可以配置缓存键包含设备类型,让移动端和桌面端拥有独立的缓存版本。

步骤2:Django模板适配请求头

因为缓存是分设备的,所以可以直接在模板里根据Cloudflare的请求头判断设备,只渲染对应广告:

{% if request.META.get('CF-Device-Type') == 'mobile' %}
<div class="ads-mobile">
    <script async type="application/javascript" src="https://cdn-ads.com/ad-mobile.js"></script> 
    <ins class="ee31" data-zoneid="68"></ins> 
    <script>(Ads = window.Ads || []).push({"goserve": {}});</script>
</div>
{% else %}
<div class="ads-desktop">
    <script async type="application/javascript" src="https://cdn-ads.com/ad-desktop.js"></script> 
    <ins class="ee31" data-zoneid="68"></ins> 
    <script>(Ads = window.Ads || []).push({"goserve": {}});</script>
</div>
{% endif %}

步骤3:配置Cloudflare缓存规则

在「规则 > 缓存规则」里新建规则,设置缓存键为{uri}_{cf-device-type},确保不同设备的页面缓存相互独立,不会出现移动端用户拿到桌面端缓存的情况。

这个方案的优势是页面加载时就只包含对应设备的脚本,比前端动态加载更高效,同时利用Cloudflare的边缘能力,不会增加源站负担。

方案3:Cloudflare Workers修改页面响应(无需改动Django代码)

如果不想修改Django模板,可以用Cloudflare Workers在边缘层直接修改返回的HTML,移除不需要的广告块:

addEventListener('fetch', event => {
  event.respondWith(handleRequest(event.request));
});

async function handleRequest(request) {
  const response = await fetch(request);
  const deviceType = request.headers.get('CF-Device-Type');
  
  // 如果无法获取设备类型或请求失败,直接返回原响应
  if (!deviceType || !response.ok) return response;
  
  const htmlContent = await response.text();
  let modifiedHtml = htmlContent;
  
  if (deviceType === 'mobile') {
    // 移除桌面端广告块(正则匹配整个广告容器)
    modifiedHtml = modifiedHtml.replace(/<div class="ads-desktop">[\s\S]*?<\/div>/, '');
  } else {
    // 移除移动端广告块
    modifiedHtml = modifiedHtml.replace(/<div class="ads-mobile">[\s\S]*?<\/div>/, '');
  }
  
  // 返回修改后的页面
  return new Response(modifiedHtml, {
    headers: response.headers,
    status: response.status
  });
}

同样需要配置分设备缓存规则,确保不同设备拿到的是对应修改后的页面。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 23:45:03