使用 Greasemonkey/Tampermonkey 保存数据供以后检索

Save data using Greasemonkey/Tampermonkey for later retrieval

我正在从事一个需要网站数据的项目。该数据的问题在于它被组织成许多不同的网页,在 URL 中带有序列号。为了解决这个问题,我在 Tampermonkey 中编写了一个简单的脚本,它循环访问这些页面并获取脚本中字符串变量中的数据。

现在真正的问题来了,我该如何存储这些数据。我知道我无法在我的 PC 上写入文件,但数据是否可以显示在浏览器的单独选项卡上,以便我可以在循环完成后将其复制并粘贴到本地文件中?我希望在每个循环中将一个字符串附加到存储中

我不想使用 GM_setValue,因为我想要原始文本格式的数据(如 .txt 文件)

但是,如果它可以在不使用外部库的情况下直接写入我 PC 上的文件,那将是首选。

I know I can't write to a file on my PC

这里有一些好消息要告诉您:是的,您可以!

var a = document.createElement("a");
a.href = "data:text,Hello World!";   //content
a.download = "Hello.txt";            //file name
a.click();

http://jsfiddle.net/DerekL/jgfhwfL0/


首先打开您的本地主机页面,master.html (http://localhost:8080/master.html):

<html>
    <head>
        <script>
            window.addEventListener("load", function(){
                //This is just like working with threads but in JavaScript
                if(location.search.length){
                    //receiver
                    var query = decodeURIComponent(location.search.slice(1));
                    var data = JSON.parse(query).value;

                    //handle data
                    localStorage.storage = +localStorage.storage + data;

                    location.href = "about:blank";  //exit
                }else{
                    //master
                    sum = document.getElementById("sum"); 
                    sum.innerText = localStorage.storage = "0";

                    window.addEventListener("storage", function(){
                        //data received from receiver
                        sum.innerText = localStorage.storage;
                    });
                }
            });
        </script>
    </head>
    <body>
        Sum: <span id="sum"></span>
    </body>
</html>

然后你就可以在任何网页中开始向它发送数据了:

var frame = document.createElement("iframe");
frame.src = 'http://localhost:8080/master.html?{"value":90}';    //port 8080
document.body.appendChild(frame);

总和计数器应在收到数据后自动更新。

一种方法是 运行 本地主机 HTTP 服务器,公开路由并使用它们来读取和写入文件,并且通常会执行用户脚本所需的所有 back-end 操作。

这是使用 Node 17 和 Express 的简单概念回显证明,但同样可以使用您喜欢的任何 back-end 技术来完成。

server.js:

const cors = require("cors"); // "^2.8.5"
const express = require("express"); // "^4.18.1"
const fs = require("fs").promises;
const path = require("path");

const dataFile = "data.json";
const app = express();
app
  .set("port", process.env.PORT || 5000)
  .use(cors())
  .use(express.json())
  .get("/", (req, res) => {
    fs.readFile(path.join(__dirname, dataFile))
      .then(file => res.send(file.toString()))
      .catch(err => res.status(404).send(err.message));
  })
  .post("/", (req, res) => {
    const p = path.join(__dirname, dataFile);
    fs.writeFile(p, JSON.stringify(req.body))
      .then(file => res.sendStatus(200))
      .catch(err => res.status(400).send(err.message));
  })
  .listen(app.get("port"), () =>
    console.log(`server listening on port ${app.get("port")}`)
  );

Tampermonkey 脚本:

const url = "http://localhost:5000";

const writeData = payload =>
  fetch(url, {
      method: "POST",
      headers: {
        "Accept": "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify(payload)
    })
    .then(response => {
      if (!response.ok) {
        throw Error(response.status);
      }
    });

const readData = () =>
  fetch(url)
    .then(response => {
      if (!response.ok) {
        throw Error(response.status);
      }
    
      return response.json();
    });

writeData({hello: "world"})
  .then(readData)
  .then(data => console.log(data)) // => {hello: 'world'}
  .catch(err => console.error(err));

除了启用 cross-origin 访问和从用户脚本而不是典型的客户端(如网页或应用程序)发送请求的新颖性之外,这里没有什么特别的。

请谨慎使用,因为这会将本地文件系统暴露给未知网站上的潜在恶意脚本运行。