我应该使用哪种缓存技术?

3

我有一个问题,关于构建一个简单的渐进式Web应用程序时使用最佳离线缓存技术的选择。

简而言之,我正在构建一款药品说明应用程序,用户需要输入条形码,点击“获取药品”,然后用户将被重定向到一个result.php文件,其中包含我从MySQL数据库中查询到的有关药品的一些基本信息(该条形码是这个简单数据库中的关键字)。

现在我想要实现离线缓存。第一次用户输入此条形码并进入结果页面时,我希望将与该条形码相关联的数据保存在缓存中。下一次当用户处于离线状态并在index.html文件中输入相同的条形码并单击提交时,它应该再次将其发送到那个结果页面,并显示先前保存的缓存数据。

现在的问题是,我不知道最好的缓存技术是什么。我找到了一个网站,解释了每种技术以及如何实现它的示例,但我不知道该选择哪个:https://jakearchibald.com/2014/offline-cookbook

有人可以给我一些适合我情况的提示吗?

这是我拥有的HTML和PHP文件(目前一切正常):

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Progressive Web Application - MAM11</title>
    <link rel="stylesheet" href="styles/main.css">
    <script src="scripts/app.js" async></script>
</head>
<body>

    <h1>Pill-Explainer</h1>

    <p>Please enter the European Article Number (EAN) of your medication below. <br>
        You can find the EAN at the outside of your medication box often starting with the number 8 and containing 13 digits in total. </p>

    <img src="images/barcode.jpg"> <br>

 <form action="http://192.168.0.104/MedicationProject/result.php" method="post">

     <input type="number" placeholder="Enter barcode" name="barcode" id="barcode"> <br>
     <input type="submit" value="Get medication" id="submit">
 </form>

</body>

<?php 
// 1. database credentials
$host = "sql7.freemysqlhosting.net";
$db_name = "sql7264357";
$username = "sql7264357";
$password = "*********";

// 2. connect to database
$con = new PDO("mysql:host={$host};dbname={$db_name}", $username, $password);

// 3. get barcode value from inputfield in previous document
$search=$_POST['barcode']; 

// 4. prepare select query
$query = 'SELECT ProductName, ActiveIngredient, Description, Leaflet 
FROM Medications WHERE Barcode = "'.$search.'"';
$stmt = $con->prepare( $query );

// 5. execute our query
$stmt->execute();

// 6. store retrieved row to the 'row' variable
$row = $stmt->fetch(PDO::FETCH_ASSOC);
?> 

<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Progressive Web Application - MAM11</title>
    <link rel="stylesheet" href="styles/result.css">
</head>
<body>

    <h1>Pill-Explainer</h1>     


 <form action="/action_page.php">

     <label>Productname:</label> 
     <textarea type="text" id="productname"><?php echo $row['ProductName']?></textarea>                

     <label>Active ingredient:</label>
     <textarea type="text" id="ingredient"><?php echo $row['ActiveIngredient']?></textarea>

     <label>Description:</label>
     <textarea type="text" id="description"><?php echo $row['Description']?></textarea>

 </form>

<div id="buttons">
    <a href="index.html">
        <img src="images/back-button.jpg">
    </a>

    <a href="<?php echo $row['Leaflet']?>">
        <button type="button">Download leaflet <br> (Internet only)</button>
    </a>
</div>

</body>

我也开始制作一个 service-worker,至少可以缓存应用程序的外壳(到目前为止也有效)。因此,我已经成功地缓存了所有文件,现在只需要在数据缓存部分得到帮助。


Google 建议使用 IndexedDB - 如果您还没有查看这些链接,那么它们可能值得一看...对我来说非常有用,因为我以前没有研究过这个问题 :) - CD001
我看到越来越多的人建议使用IndexedDB。我会更深入地研究一下,谢谢! - Toufik
3个回答

1

听起来是一个有趣的项目。

有很多方法可以解决这个问题,但我认为以下方法最简单。你在https://jakearchibald.com找到了一个很好的资源,他是离线优先和PWA方面的思想领袖之一,绝对值得关注。

在你的情况下,似乎应该使用IndexedDB,在现代浏览器中内置的数据库,它允许在浏览器缓存中存储大量结构化数据,包括JSON。(https://developer.mozilla.org/en-US/docs/Web/API/IndexedDB_API)然后,你可以扩展你的服务工作者以拦截请求,并在向后端发出调用之前首先检查IndexedDB中是否有数据。我来自NodeJS背景,所以在PHP世界中可能略有不同,但我认为以下基本步骤应该相同:

  1. 第一次调用检索药物X的数据
  2. 将数据呈现在页面上,并将数据作为JSON缓存到IndexedDB中
  3. 用户再次搜索药物X
  4. Service Worker入口将拦截该调用并首先检查是否存在有效的IndexedDB,即药物X。 如果存在,则应使用缓存中的数据,否则应允许服务调用完成。

我知道这只是一个非常简化的答案,但我相信这将是您实现此目标的基本步骤。


1
谢谢JonnyIrving。我确实认为它将涉及这些基本步骤。我唯一不知道的是如何在我的php文件中显示数据库的结果。我理解条形码可以作为关键路径(因为这些是唯一的),但是当再次在离线模式下点击提交按钮时,它应该将先前保存的数据检索出来并显示在我的文本框中,而不是在浏览器的控制台中。 - Toufik
如果您按照上述步骤进行操作,那么您就不需要编写代码来处理离线和在线会话的差异,因为服务工作者将简单地拦截并解决原本应该发送到服务的调用,并改为使用 IndexedDB 中的数据进行响应。 - JonnyIrving

1
我建议使用indexDB,因为它在性能和开发方面都有帮助,可以查询和获取特定结果。您的mysql数据将以JSON形式提供给浏览器(如果没有,请这样做,因为我没有理由不使用),因此可以直接保存在indexDB中。其次,indexDB是NoSql数据库,因此很容易将Mysql(SQL)数据存储在任何NoSql数据库中,因为它们已经被结构化且NoSql数据库是动态的。如果使用大量条形码,则localStorage会成为一个问题,您将存储在本地存储中,因此本地存储大小将增加,现在需要通过每个条目进行查询,直到获得请求的条形码,但在indexDB中,可以使用索引。Cookies用于跟踪、分析数据等。因此,最终选择indexDB。如果有任何疑问,请随时留言。

PHP无法工作,因为IndexDB是客户端数据库,只有JavaScript可以工作。您需要使用JavaScript编写代码,将数据存储在IndexDB中,并从IndexDB获取数据,然后在浏览器上显示。但不是使用.php,因为PHP在服务器端执行并由PHP解释器提供HTML输出到浏览器。 - Meena Pintu
我知道,但我并不是说我会使用PHP将数据存储在indexDB中。我的PHP文件包含一些HTML代码,我想将我存储在indexDB中的内容显示在这些HTML标签中(在这种情况下,我的表单)。我该怎么做?找不到一些好的例子。 - Toufik
或者,我应该创建一个新的HTML页面,与result.php页面具有相同的样式和所有内容,以显示indexDB结果。只有在浏览器离线时才会触发此页面。这是你的意思吗? - Toufik
@Toufik,正如你所提到的,你的应用程序也应该可以离线工作,在这种情况下,PHP将无法工作,因为页面不会被缓存。因此,创建一个单独的HTML文件是个好主意。在PHP中只需处理并以JSON格式返回数据,对于那些使用Index DB数据的数据,可以使用JavaScript帮助来使用同一HTML文件。 - Meena Pintu
你可以使用 jQuery 向你的 div 元素添加元素。 - Meena Pintu
显示剩余3条评论

0

把数据存储在 localStorage 中怎么样?

你可以用 barcode 作为键,将 stringifed 数据放置在那里。


显然,这种方法不如indexedDB好用,因为缓存在处理此类数据时可能会迅速增加。据我所知,indexedDB可以更好地处理这个问题。 - Toufik

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接