首页
/ 断网也能用:qrcode.js与PWA打造离线二维码生成解决方案

断网也能用:qrcode.js与PWA打造离线二维码生成解决方案

2026-02-04 04:26:43作者:廉彬冶Miranda

你是否遇到过这样的情况:在没有网络的环境下急需生成二维码分享链接或信息,却发现常用的在线工具完全无法使用?旅行途中、网络中断时、偏远地区工作——这些场景下,离线可用的工具变得至关重要。本文将带你使用qrcode.js结合PWA(Progressive Web App,渐进式网页应用)技术,构建一个完全离线可用的二维码生成工具,让你随时随地都能生成所需的二维码。

读完本文后,你将能够:

  • 理解qrcode.js的核心功能和使用方法
  • 掌握将普通网页转换为PWA的关键步骤
  • 构建一个可以离线工作的二维码生成应用
  • 了解如何将应用安装到不同设备的主屏幕

认识qrcode.js:轻量级二维码生成库

qrcode.js是一个跨浏览器的JavaScript二维码生成库,它的核心优势在于无需任何外部依赖,纯前端实现二维码生成。项目结构简洁明了,主要包含几个关键文件:

该库支持多种输出格式,包括Canvas、SVG和Table,能够适应不同的浏览器环境。从qrcode.js源码中可以看到,它通过QRCode类封装了完整的二维码生成逻辑,支持自定义尺寸、颜色等多种参数。

快速上手:使用qrcode.js生成基础二维码

使用qrcode.js创建二维码非常简单,只需要几行代码就能实现。让我们看看index.html中的基础示例:

<input id="text" type="text" value="http://example.com" style="width:80%" /><br />
<div id="qrcode" style="width:100px; height:100px; margin-top:15px;"></div>

<script type="text/javascript">
// 初始化QRCode实例
var qrcode = new QRCode(document.getElementById("qrcode"), {
	width : 100,
	height : 100
});

// 生成二维码的函数
function makeCode () {		
	var elText = document.getElementById("text");
	
	if (!elText.value) {
		alert("请输入文本");
		elText.focus();
		return;
	}
	
	qrcode.makeCode(elText.value);
}

// 页面加载时生成初始二维码
makeCode();

// 监听输入框事件,实时更新二维码
$("#text").
	on("blur", function () {
		makeCode();
	}).
	on("keydown", function (e) {
		if (e.keyCode == 13) {
			makeCode();
		}
	});
</script>

这段代码实现了一个基本的二维码生成器:创建输入框和二维码容器,初始化QRCode实例,然后监听输入框的变化来实时更新二维码。你可以通过修改参数来自定义二维码的尺寸、颜色等属性。

实现离线功能:PWA技术解析

要让应用实现离线可用,我们需要借助PWA的核心技术——Service Worker和Manifest文件。Service Worker是一个运行在后台的脚本,可以拦截网络请求并缓存资源,从而实现离线访问。

1. 创建Manifest文件

首先,创建一个manifest.json文件,用于定义应用的名称、图标、启动方式等信息:

{
  "name": "离线二维码生成器",
  "short_name": "二维码生成器",
  "description": "一个可以离线使用的二维码生成工具",
  "start_url": "index.html",
  "display": "standalone",
  "background_color": "#ffffff",
  "theme_color": "#4285f4",
  "icons": [
    {
      "src": "icon-192x192.png",
      "sizes": "192x192",
      "type": "image/png"
    },
    {
      "src": "icon-512x512.png",
      "sizes": "512x512",
      "type": "image/png"
    }
  ]
}

2. 注册Service Worker

接下来,在我们的HTML文件中添加Service Worker的注册代码。修改index.html,在<head>标签内添加以下内容:

<link rel="manifest" href="manifest.json">
<meta name="theme-color" content="#4285f4">
<script>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('sw.js').then(function(registration) {
      console.log('ServiceWorker registration successful');
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}
</script>

3. 编写Service Worker脚本

创建sw.js文件,实现资源缓存和离线访问逻辑:

var CACHE_NAME = 'qrcode-generator-v1';
var CACHED_FILES = [
  './',
  'index.html',
  'qrcode.min.js',
  'jquery.min.js',
  'icon-192x192.png'
];

// 安装阶段:缓存必要的文件
self.addEventListener('install', function(event) {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(function(cache) {
        return cache.addAll(CACHED_FILES);
      })
  );
});

// 激活阶段:清理旧版本缓存
self.addEventListener('activate', function(event) {
  event.waitUntil(
    caches.keys().then(function(cacheNames) {
      return Promise.all(
        cacheNames.map(function(cacheName) {
          if (cacheName !== CACHE_NAME) {
            return caches.delete(cacheName);
          }
        })
      );
    })
  );
});

//  fetch事件:优先从缓存获取资源,失败时回退到网络
self.addEventListener('fetch', function(event) {
  event.respondWith(
    caches.match(event.request)
      .then(function(response) {
        if (response) {
          return response;
        }
        return fetch(event.request);
      })
  );
});

完整实现:离线二维码生成器

综合以上步骤,我们可以构建一个完整的离线二维码生成应用。下面是改造后的完整index.html代码:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="ko" lang="ko">
<head>
<title>离线二维码生成器</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta name="viewport" content="width=device-width,initial-scale=1,user-scalable=no" />
<meta name="theme-color" content="#4285f4">
<link rel="manifest" href="manifest.json">
<script type="text/javascript" src="jquery.min.js"></script>
<script type="text/javascript" src="qrcode.js"></script>
<style>
  body { 
    font-family: Arial, sans-serif; 
    max-width: 500px; 
    margin: 0 auto; 
    padding: 20px; 
  }
  #text { 
    width: 100%; 
    padding: 10px; 
    font-size: 16px; 
    margin-bottom: 20px; 
  }
  #qrcode { 
    width: 256px; 
    height: 256px; 
    margin: 0 auto; 
  }
  .controls { 
    margin-top: 20px; 
    text-align: center; 
  }
  button { 
    padding: 10px 20px; 
    background-color: #4285f4; 
    color: white; 
    border: none; 
    border-radius: 5px; 
    cursor: pointer; 
    font-size: 16px; 
  }
</style>
<script>
if ('serviceWorker' in navigator) {
  window.addEventListener('load', function() {
    navigator.serviceWorker.register('sw.js').then(function(registration) {
      console.log('ServiceWorker registration successful');
    }, function(err) {
      console.log('ServiceWorker registration failed: ', err);
    });
  });
}
</script>
</head>
<body>
  <h1>离线二维码生成器</h1>
  <p>输入文本或URL,生成对应的二维码。本应用可离线使用。</p>
  
  <input id="text" type="text" value="https://example.com" style="width:80%" /><br />
  <div id="qrcode" style="width:256px; height:256px; margin:20px auto;"></div>
  
  <div class="controls">
    <button onclick="downloadQRCode()">下载二维码</button>
  </div>

  <script type="text/javascript">
  var qrcode = new QRCode(document.getElementById("qrcode"), {
    width : 256,
    height : 256,
    colorDark : "#000000",
    colorLight : "#ffffff",
    correctLevel : QRCode.CorrectLevel.H
  });

  function makeCode () {		
    var elText = document.getElementById("text");
    
    if (!elText.value) {
      alert("请输入文本");
      elText.focus();
      return;
    }
    
    qrcode.makeCode(elText.value);
  }

  function downloadQRCode() {
    var canvas = document.querySelector("#qrcode canvas");
    if (canvas) {
      var link = document.createElement("a");
      link.download = "qrcode.png";
      link.href = canvas.toDataURL("image/png");
      link.click();
    } else {
      alert("请先生成二维码");
    }
  }

  makeCode();

  $("#text").
    on("blur", function () {
      makeCode();
    }).
    on("keydown", function (e) {
      if (e.keyCode == 13) {
        makeCode();
      }
    });
  </script>
</body>
</html>

测试与部署

要测试离线功能,你需要通过HTTP服务器运行应用(Service Worker需要在安全上下文或localhost中运行)。你可以使用简单的Python服务器:

python -m http.server 8000

然后在浏览器中访问http://localhost:8000,首次加载后,即使断开网络,应用仍然可以正常工作。

总结与展望

通过本文的介绍,我们学习了如何使用qrcode.js库生成二维码,并结合PWA技术将其改造为离线应用。这个工具在网络不稳定或完全断网的环境下非常实用,例如:

  • 旅行中在没有漫游网络时生成WiFi密码二维码
  • 会议现场分享资料链接,无需依赖现场网络
  • 偏远地区工作时生成产品信息二维码

该项目还有进一步优化的空间,比如添加更多自定义选项(二维码尺寸、颜色、容错级别)、支持批量生成、添加历史记录等功能。你可以基于qrcode.js的源码进行扩展,实现更多个性化需求。

希望这个离线二维码生成工具能解决你在无网络环境下的信息分享需求!如果觉得有用,请将它安装到你的设备主屏幕,随时备用。

登录后查看全文
热门项目推荐
相关项目推荐