【问题标题】:What caching technique to use for my situation?针对我的情况使用什么缓存技术?
【发布时间】:2024-04-12 11:00:02
【问题描述】:

我有一个关于用于我当前正在构建的简单渐进式 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 - 如果您还没有检查这些链接,可能值得检查......这不是我以前研究过的东西,所以无论如何它对我很有用: )
  • 我看到越来越多的人推荐这个 IndexedDB。我会对此进行更多研究,谢谢!

标签: javascript php html service-worker


【解决方案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. 用户再次搜索 Pill X
  4. Service Worker 条目将拦截调用并首先检查是否存在用于该搜索的有效 IndexedDB,即药丸 X。 如果有,则应使用缓存中的数据,如果没有,则应允许完成服务调用。

我知道这是一个非常简单的答案,但我相信这将是您实现这一目标的基本过程。

【讨论】:

  • 谢谢乔尼欧文。我确实认为它会达到这些基本步骤。我唯一不知道的是如何在我的 php 文件中显示数据库的结果。我知道条形码可以用作键路径(因为它们是唯一的)但是在离线模式下再次点击提交按钮的那一刻,它应该显示从 MySQL 检索到的较早保存的数据到我的文本框中,而不是在浏览器的控制台中.
  • 好吧,如果您按照上述步骤进行操作,那么您将不需要代码来以不同的方式处理离线会话和在线会话,因为服务工作者会简单地拦截并解决对服务进行的调用而是使用 IndexedDB 中的数据进行响应。
【解决方案2】:

我会说使用 indexDB,因为它在性能和开发方面也有助于查询和获取特定结果。

您的 mysql 数据将以 JSON 的形式作为服务器到浏览器(如果不这样做,因为我看不出有任何不使用它的理由),因此您可以直接保存在 indexDB 中。

第二件事 indexDB 在 NoSql 数据库中,因此很容易将 Mysql (SQL) 数据存储在任何 NoSql 数据库中,因为它们已经结构化并且 NoSql 数据库是动态的。

如果假设使用大量条形码,localStorage 将是一个问题,您将存储在 local-storage 中,因此本地存储大小会增长,现在查询您必须通过每个条目进行查询,直到您获得请求条形码但是在 indexDB 中,您可以使用索引。

Cookies 用于跟踪器、分析数据等。

所以最后选择 indexDB。

如果您有任何疑问,请随时留言

【讨论】:

  • 我认为这会奏效。有很多关于如何使用 IndexDB 的示例。我只需要找到一种方法来在欲望页面中显示这个数据库的结果(在这种情况下,我的 .php 文件)。到目前为止,我只看到结果显示在浏览器的控制台中。
  • php 不能工作,因为 indexDB 是客户端数据库,只有 javascript 可以工作。您需要用 javascript 编写代码,将数据存储在 indexDB 中并从 indexDB 中获取数据,然后显示在浏览器上。但不是 .php,因为 php 在服务器端执行并输出 html 由 php 解释器提供给浏览器。
  • 我知道,但我并不是说我会使用php将数据存储在indexDB中。我的 PHP 文件包含一些 HTML 代码,我想将我存储在 indexDB 中的任何内容显示到这些 HTML 标记中(在本例中为我的表单)。我该怎么做?在这方面找不到一些好的例子。
  • 或者..我应该创建一个新的 HTML 页面,其样式和所有内容都与将显示 indexDB 结果的 result.php 页面相同。此页面仅应在浏览器离线时触发。你是这个意思吗?
  • @Toufik 正如你所提到的,你的应用程序也应该离线工作,在这种情况下 php 将无法工作,因为页面不会被缓存。所以是的,创建一个单独的 html 文件是个好主意。在 php 中只处理以 json 格式返回的数据,并且对于索引数据库数据也使用相同的 html 文件在 javascript 的帮助下使用相同的 html 文件
【解决方案3】:

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

您将barcode 作为键并将stringifed 数据放在那里。

【讨论】:

  • 显然这不会像 indexedDB 那样好用,因为缓存会随着这种数据的大小迅速增加。据我了解,IndexedDB 可以更好地处理这个问题。
最近更新 更多