我正在处理一个需要网站数据的项目。这些数据的问题在于,它被组织成许多不同的网页,URL中有序列号。为了解决这个问题,我在Tampermonkey中编写了一个简单的脚本,它在这些页面中循环,并在脚本中的字符串变量中获取数据。
现在真正的问题来了,我该如何存储这些数据。我知道我不能在电脑上写入文件,但数据是否可以显示在浏览器的单独选项卡上,以便在循环完成后将其复制并粘贴到本地文件中?我希望在每个循环中添加一个字符串到存储中
我不想使用GM_setValue
,因为我想要原始文本格式的数据(如.txt
文件)
然而,如果它可以在不使用外部库的情况下直接写入我电脑上的文件,那将是首选。
我知道我不能在我的电脑上写入文件
给你一些好消息:是的,你可以!
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);
总和计数器应在收到数据后自动更新。
一种方法是运行localhost HTTP服务器,公开路由并使用它们来读取和写入文件,通常还可以为用户脚本完成所需的所有后端工作。
这里有一个使用Node 17和Express的简单概念验证回显,但您喜欢的任何后端技术都可以做到这一点。
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));
这里没有什么特别的,除了允许跨源访问,以及从用户脚本而不是像网页或应用程序这样的典型客户端发送请求的新颖性。
请小心,因为这会使本地文件系统暴露在未知网站上运行的潜在恶意脚本中。