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

Leaflet加载OpenStreetMap瓦片问题:PDF导出时地图未完全加载如何解决

问题:打印PDF时Leaflet地图瓦片未完全加载,出现NS_BINDING_ABORTED错误

使用Laravel 8.83和PHP 7.4制作PDF导出视图,包含图片、文本和OpenStreetMap地图区域,页面加载正常,但浏览器打印预览中地图瓦片未完全加载,Firefox控制台报NS_BINDING_ABORTED错误,如何强制瓦片完全加载?

原视图代码

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TEST</title>
<style>
    body {
        font-size: 12px;
        color: #000;
        max-width: 720px;

    }
    * {
        font-family: 'muli', sans-serif;
        font-style: normal;
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    .article-pdf {
        padding: 10px;
        max-width: 720px;
        margin: 0 auto;
    }
    .row {
        display: flex;
        width: 100%;
        align-items: flex-start;
        margin: 0 -15px;
    }
    .col-6 {
        width: 50%;
        padding: 0 15px;
    }
    .image-container {
        position: relative;
    }
    .image-container::after {
        content: "";
        display: block;
        padding-bottom: 100%;
        border: 0.5px solid grey;
    }
    .image {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        padding: 7px;
    }
    .card {
        position: relative;
        z-index: 0;
    }
    .card .map-container {
        margin-left: 0;
        margin-right: 0;
        position: absolute;
        left: 0;
        width: 100%;
        height: 100%;
    }
    .card::after {
        content: "";
        display: block;
        padding-bottom: 100%;
    }
    .topic {
        font-size: 12px;
        font-style: normal;
        line-height: 30px;
        border-bottom: solid 1px #000;
    }
    .title {
        margin-bottom: 10px;
        font-size: 30px;
        line-height: 38px;
    }
    .subtitle em {
        font-weight: normal;
    }
</style>

<link href="{{ asset('css/site/leaflet.css') }}" rel="stylesheet">
</head>

<body class="lang-fr" onload="window.print()">
<article class="article-pdf">
    <p class="topic">---[ TEST PDF ]---</p>
    <h1 class="title">Archive title</h1>
        <div class="row">
            <div class="col-6">
                <div class="image-container">
                    <img class="image img-portrain}" src="{{ asset('storage/images/medium/' . $archive->resource) }}" alt="">
            </div>
        </div>
        <div class="col-6">
            <div class="card">
                <div class="map-container" id="map"></div>
            </div>
        </div>
    </div>
</article>

<script src="{{ asset('js/site/leaflet.js') }}" defer></script>
<script src="{{ asset('js/site/article.js') }}" defer></script>

</body>
</html>

原JS代码

const search_map = L.map('map').setView([28.787, 4.043], 5)
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {minZoom: 4, maxZoom: 19}).addTo(search_map)
解决方案

核心问题是window.print()在地图瓦片加载完成前触发,导致浏览器中断瓦片请求。可通过以下方式解决:

  • 监听瓦片加载完成事件再触发打印
    Leaflet的TileLayer提供load事件,所有可见瓦片加载完成时触发,监听该事件确保瓦片加载完毕后再调用打印。

  • 移除提前触发的打印事件
    删除<body>标签的onload="window.print()",避免页面刚加载就触发打印。

修改后的JS代码

const search_map = L.map('map').setView([28.787, 4.043], 5);
const tiles = L.tileLayer('https://tile.openstreetmap.org/{z}/{x}/{y}.png', {
    minZoom: 4, 
    maxZoom: 19
}).addTo(search_map);

// 监听所有可见瓦片加载完成事件
tiles.on('load', function() {
    // 加100ms延迟确保地图渲染完全,再触发打印
    setTimeout(() => {
        window.print();
    }, 100);
});

修改后的视图代码

<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>TEST</title>
<style>
    body {
        font-size: 12px;
        color: #000;
        max-width: 720px;

    }
    * {
        font-family: 'muli', sans-serif;
        font-style: normal;
        box-sizing: border-box;
        margin: 0;
        padding: 0;
    }
    .article-pdf {
        padding: 10px;
        max-width: 720px;
        margin: 0 auto;
    }
    .row {
        display: flex;
        width: 100%;
        align-items: flex-start;
        margin: 0 -15px;
    }
    .col-6 {
        width: 50%;
        padding: 0 15px;
    }
    .image-container {
        position: relative;
    }
    .image-container::after {
        content: "";
        display: block;
        padding-bottom: 100%;
        border: 0.5px solid grey;
    }
    .image {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
        padding: 7px;
    }
    .card {
        position: relative;
        z-index: 0;
    }
    .card .map-container {
        margin-left: 0;
        margin-right: 0;
        position: absolute;
        left: 0;
        width: 100%;
        height: 100%;
    }
    .card::after {
        content: "";
        display: block;
        padding-bottom: 100%;
    }
    .topic {
        font-size: 12px;
        font-style: normal;
        line-height: 30px;
        border-bottom: solid 1px #000;
    }
    .title {
        margin-bottom: 10px;
        font-size: 30px;
        line-height: 38px;
    }
    .subtitle em {
        font-weight: normal;
    }
</style>

<link href="{{ asset('css/site/leaflet.css') }}" rel="stylesheet">
</head>

<body class="lang-fr">
<article class="article-pdf">
    <p class="topic">---[ TEST PDF ]---</p>
    <h1 class="title">Archive title</h1>
        <div class="row">
            <div class="col-6">
                <div class="image-container">
                    <img class="image img-portrain" src="{{ asset('storage/images/medium/' . $archive->resource) }}" alt="">
            </div>
        </div>
        <div class="col-6">
            <div class="card">
                <div class="map-container" id="map"></div>
            </div>
        </div>
    </div>
</article>

<script src="{{ asset('js/site/leaflet.js') }}" defer></script>
<script src="{{ asset('js/site/article.js') }}" defer></script>

</body>
</html>

额外说明

  • 100ms延迟是为了处理Leaflet最后的渲染步骤,避免地图未完全绘制就进入打印预览,可根据实际加载速度调整。
  • 若瓦片加载仍不稳定,可尝试增加延迟时间,或检查地图容器的尺寸是否在初始化时已明确(当前代码中容器尺寸通过CSS伪元素设置,是可行的)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 07:13:05