first commit
This commit is contained in:
commit
92d0440a2d
8
LICENSE
Normal file
8
LICENSE
Normal file
@ -0,0 +1,8 @@
|
||||
The MIT License (MIT)
|
||||
Copyright © 2025 <copyright holders>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
89
README.md
Normal file
89
README.md
Normal file
@ -0,0 +1,89 @@
|
||||
# Cookie Extract (Browser Extension)
|
||||
|
||||
[](https://addons.mozilla.org/zh-CN/firefox/addon/cookie-extract/) <!-- 在发布后替换 Firefox 链接 -->
|
||||
[](https://chrome.google.com/webstore/detail/your-chrome-store-id) <!-- 在发布后替换 Chrome 链接 -->
|
||||
[](https://microsoftedge.microsoft.com/addons/detail/your-edge-store-id) <!-- 在发布后替换 Edge 链接 -->
|
||||
[](https://opensource.org/licenses/MIT) <!-- 如果你使用 MIT 协议 -->
|
||||
|
||||
一个简单的浏览器扩展,适用于 **Firefox, Chrome, 和 Edge**,可以帮助你快速提取和复制当前标签页中的 SESSION cookie 以及响应头中的 `Set-Cookie` 值。
|
||||
|
||||
## 功能
|
||||
|
||||
- **提取 SESSION Cookie:** 查找并显示当前页面域下的 `SESSION` cookie 值。
|
||||
- **提取 Header Cookies:** 捕获并显示当前页面主文档(HTML)加载时的 `Set-Cookie` 响应头。
|
||||
- **一键复制:** 提供单独的按钮,方便地将 `SESSION` cookie 或所有 Header Cookies 复制到剪贴板。
|
||||
- **清晰展示:** 在扩展弹出窗口中清晰地列出提取到的 Cookie 信息。
|
||||
|
||||
## 安装方法
|
||||
|
||||
### 方式一:从官方商店 (推荐)
|
||||
|
||||
- Firefox:
|
||||
1. 访问 [Cookie Extract on Firefox Add-ons](https://addons.mozilla.org/zh-CN/firefox/addon/cookie-extract/) <!-- 在发布后替换这里的链接 -->
|
||||
2. 点击 "添加到 Firefox" 按钮。
|
||||
- Chrome:
|
||||
1. 访问 [Cookie Extract on Chrome Web Store](https://chrome.google.com/webstore/detail/your-chrome-store-id) <!-- 在发布后替换这里的链接 -->
|
||||
2. 点击 "添加到 Chrome" 按钮。
|
||||
- Microsoft Edge:
|
||||
1. 访问 [Cookie Extract on Microsoft Edge Add-ons](https://microsoftedge.microsoft.com/addons/detail/your-edge-store-id) <!-- 在发布后替换这里的链接 -->
|
||||
2. 点击 "获取" 按钮。
|
||||
|
||||
### 方式二:从源代码 (用于开发或测试)
|
||||
|
||||
1. 下载或克隆此仓库到本地文件夹。
|
||||
2. 对于 Firefox:
|
||||
- 打开 Firefox 浏览器。
|
||||
- 在地址栏输入 `about:debugging#/runtime/this-firefox` 并回车。
|
||||
- 点击 "加载临时附加组件..." 按钮。
|
||||
- 导航到你保存扩展代码的文件夹,选择 `manifest.json` 文件并打开。
|
||||
3. 对于 Chrome:
|
||||
- 打开 Chrome 浏览器。
|
||||
- 在地址栏输入 `chrome://extensions` 并回车。
|
||||
- 确保右上角的 "开发者模式 (Developer mode)" 开关已启用。
|
||||
- 点击左上角的 "加载已解压的扩展程序 (Load unpacked)" 按钮。
|
||||
- 导航并选择包含扩展代码的**文件夹** (包含 `manifest.json` 的那个文件夹),然后点击 "选择文件夹"。
|
||||
4. 对于 Microsoft Edge:
|
||||
- 打开 Edge 浏览器。
|
||||
- 在地址栏输入 `edge://extensions` 并回车。
|
||||
- 确保左下角的 "开发人员模式 (Developer mode)" 开关已启用。
|
||||
- 点击 "加载解压缩的扩展 (Load unpacked)" 按钮。
|
||||
- 导航并选择包含扩展代码的**文件夹** (包含 `manifest.json` 的那个文件夹),然后点击 "选择文件夹"。
|
||||
|
||||
## 使用方法
|
||||
|
||||
1. 导航到你想要提取 Cookie 的网页。
|
||||
2. 点击浏览器工具栏中的 "Cookie Extract" 图标(通常是一个小饼干或者你设置的图标)。
|
||||
3. 扩展的弹出窗口将会显示:
|
||||
- 当前页面的 `SESSION` cookie (如果存在),格式为 `SESSION=xxx`。
|
||||
- 页面加载时响应头中的所有 `Set-Cookie` 值列表 (如果存在)。
|
||||
4. 点击对应的 "复制" 按钮,将所需信息复制到剪贴板。
|
||||
|
||||
## 权限说明
|
||||
|
||||
为了正常工作,此扩展需要以下权限:
|
||||
|
||||
- `cookies`: 读取当前标签页域下的 Cookie (用于获取 SESSION cookie)。
|
||||
- `activeTab`: 允许扩展在用户点击图标时访问当前激活的标签页信息(如 URL),这是获取特定标签页 Cookie 和 Header 的安全方式。
|
||||
- `webRequest`: 访问网络请求数据,特别是需要读取服务器响应头 (`Set-Cookie`)。
|
||||
- `<all_urls>` 或特定主机权限 (例如 `*://*.example.com/*`): `cookies` 和 `webRequest` 权限需要指定作用域。`activeTab` 可以在用户交互时临时授权,但 `webRequest` 通常需要更明确的权限声明才能捕获后台请求的头信息。请根据你的 `manifest.json` 文件确认实际使用的权限。
|
||||
- `clipboardWrite`: 将提取到的 Cookie 文本写入用户的剪贴板。
|
||||
|
||||
*注意:这些权限在 Firefox, Chrome, 和 Edge 上的功能类似。*
|
||||
|
||||
## 隐私政策
|
||||
|
||||
本扩展完全在你的本地浏览器中运行。它不会收集、存储或传输任何你的浏览数据或 Cookie 信息到任何外部服务器。所有处理都在本地完成。
|
||||
|
||||
## 图标替换说明
|
||||
|
||||
如果你是从源代码构建,可以替换 `images` 文件夹中的图标文件:
|
||||
|
||||
- `icon16.png` (16x16 像素)
|
||||
- `icon48.png` (48x48 像素)
|
||||
- `icon128.png` (128x128 像素)
|
||||
|
||||
你可以使用在线工具如 [Favicon Generator](https://favicon.io/) 来创建这些图标。
|
||||
|
||||
## 贡献 & 问题反馈
|
||||
|
||||
欢迎提出 Issue 或 Pull Request 来改进这个扩展!
|
BIN
images/icon128.png
Normal file
BIN
images/icon128.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 6.5 KiB |
BIN
images/icon16.png
Normal file
BIN
images/icon16.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 622 B |
BIN
images/icon48.png
Normal file
BIN
images/icon48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.8 KiB |
8
images/placeholder.txt
Normal file
8
images/placeholder.txt
Normal file
@ -0,0 +1,8 @@
|
||||
请在此文件夹中添加以下图标文件:
|
||||
|
||||
- icon16.png (16x16像素)
|
||||
- icon48.png (48x48像素)
|
||||
- icon128.png (128x128像素)
|
||||
|
||||
推荐使用"cookie"或"剪贴板"相关的简单图标。
|
||||
你可以使用在线工具如Favicon Generator (https://favicon.io/)创建这些图标。
|
33
manifest.json
Normal file
33
manifest.json
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"manifest_version": 3,
|
||||
"name": "Cookie Extract",
|
||||
"version": "1.1",
|
||||
"description": "一个简单的 浏览器扩展 (支持 Firefox, Edge, Chrome),可以帮助你快速提取和复制当前标签页中的 SESSION cookie 以及响应头中的 Set-Cookie 值。",
|
||||
"permissions": [
|
||||
"cookies",
|
||||
"activeTab",
|
||||
"clipboardWrite",
|
||||
"scripting"
|
||||
],
|
||||
"host_permissions": [
|
||||
"<all_urls>"
|
||||
],
|
||||
"action": {
|
||||
"default_popup": "popup.html",
|
||||
"default_icon": {
|
||||
"16": "images/icon16.png",
|
||||
"48": "images/icon48.png",
|
||||
"128": "images/icon128.png"
|
||||
}
|
||||
},
|
||||
"icons": {
|
||||
"16": "images/icon16.png",
|
||||
"48": "images/icon48.png",
|
||||
"128": "images/icon128.png"
|
||||
},
|
||||
"browser_specific_settings": {
|
||||
"gecko": {
|
||||
"id": "pjbghgochhcefganlefmajbhmemcmhbc@ui-beam.com"
|
||||
}
|
||||
}
|
||||
}
|
55
popup.html
Normal file
55
popup.html
Normal file
@ -0,0 +1,55 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>Cookie Extract</title>
|
||||
<style>
|
||||
body {
|
||||
width: 300px;
|
||||
padding: 15px;
|
||||
font-family: Arial, sans-serif;
|
||||
}
|
||||
button {
|
||||
background-color: #4285f4;
|
||||
color: white;
|
||||
border: none;
|
||||
padding: 8px 16px;
|
||||
border-radius: 4px;
|
||||
cursor: pointer;
|
||||
margin-bottom: 10px;
|
||||
width: 100%;
|
||||
}
|
||||
button:hover {
|
||||
background-color: #3367d6;
|
||||
}
|
||||
button.secondary {
|
||||
background-color: #34a853;
|
||||
}
|
||||
button.secondary:hover {
|
||||
background-color: #2d9045;
|
||||
}
|
||||
#result {
|
||||
margin-top: 10px;
|
||||
padding: 10px;
|
||||
border: 1px solid #ddd;
|
||||
border-radius: 4px;
|
||||
background-color: #f5f5f5;
|
||||
min-height: 20px;
|
||||
word-break: break-all;
|
||||
}
|
||||
.success {
|
||||
color: green;
|
||||
}
|
||||
.error {
|
||||
color: red;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h2>Cookie Extract</h2>
|
||||
<button id="copyCookie">复制SESSION Cookie</button>
|
||||
<button id="copyAllCookies" class="secondary">复制Header Cookie</button>
|
||||
<div id="result"></div>
|
||||
<script src="popup.js"></script>
|
||||
</body>
|
||||
</html>
|
248
popup.js
Normal file
248
popup.js
Normal file
@ -0,0 +1,248 @@
|
||||
document.addEventListener('DOMContentLoaded', function() {
|
||||
const copyButton = document.getElementById('copyCookie');
|
||||
const copyAllButton = document.getElementById('copyAllCookies');
|
||||
const resultDiv = document.getElementById('result');
|
||||
|
||||
// 复制SESSION cookie的功能
|
||||
copyButton.addEventListener('click', function() {
|
||||
// 获取当前标签页信息
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
const currentTab = tabs[0];
|
||||
const url = new URL(currentTab.url);
|
||||
|
||||
// 获取域名及其父域名下的所有cookie
|
||||
// 例如:如果当前网址是breeze.opd.netease.com,也会查找netease.com的cookie
|
||||
const domain = url.hostname;
|
||||
const domains = getDomainAndParents(domain);
|
||||
|
||||
// 创建一个Promise数组,每个Promise获取一个域的cookies
|
||||
const cookiePromises = domains.map(domain => {
|
||||
return new Promise((resolve) => {
|
||||
chrome.cookies.getAll({domain: domain}, (cookies) => {
|
||||
resolve(cookies || []);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 合并所有域名下的cookie结果
|
||||
Promise.all(cookiePromises).then(cookiesArrays => {
|
||||
// 合并所有cookie数组
|
||||
const allCookies = [].concat(...cookiesArrays);
|
||||
|
||||
// 查找名为SESSION的cookie(不区分大小写)
|
||||
const sessionCookie = allCookies.find(cookie =>
|
||||
cookie.name.toUpperCase() === 'SESSION');
|
||||
|
||||
if (sessionCookie) {
|
||||
// 格式化为SESSION=xxx
|
||||
const cookieText = `SESSION=${sessionCookie.value}`;
|
||||
|
||||
// 复制到剪贴板
|
||||
navigator.clipboard.writeText(cookieText)
|
||||
.then(() => {
|
||||
resultDiv.textContent = '已复制: ' + cookieText;
|
||||
resultDiv.className = 'success';
|
||||
})
|
||||
.catch(err => {
|
||||
resultDiv.textContent = '复制失败: ' + err;
|
||||
resultDiv.className = 'error';
|
||||
});
|
||||
} else {
|
||||
// 尝试从document.cookie中提取,使用scripting API
|
||||
chrome.scripting.executeScript({
|
||||
target: {tabId: tabs[0].id},
|
||||
func: function() {
|
||||
// 获取所有cookie
|
||||
const cookies = document.cookie.split(';');
|
||||
// 查找SESSION cookie
|
||||
let sessionCookie = null;
|
||||
for (let i = 0; i < cookies.length; i++) {
|
||||
const cookie = cookies[i].trim();
|
||||
if (cookie.toUpperCase().startsWith('SESSION=')) {
|
||||
sessionCookie = cookie;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return sessionCookie;
|
||||
}
|
||||
}).then(injectionResults => {
|
||||
const result = injectionResults[0];
|
||||
if (result && result.result) {
|
||||
navigator.clipboard.writeText(result.result)
|
||||
.then(() => {
|
||||
resultDiv.textContent = '已复制: ' + result.result;
|
||||
resultDiv.className = 'success';
|
||||
})
|
||||
.catch(err => {
|
||||
resultDiv.textContent = '复制失败: ' + err;
|
||||
resultDiv.className = 'error';
|
||||
});
|
||||
} else {
|
||||
// 如果仍未找到,尝试从HTTP头部中解析(仅用于演示,实际上扩展无法直接读取HTTP头)
|
||||
resultDiv.textContent = '没有找到SESSION cookie,请确认网页包含此cookie';
|
||||
resultDiv.className = 'error';
|
||||
}
|
||||
}).catch(err => {
|
||||
resultDiv.textContent = '脚本执行失败: ' + err.message;
|
||||
resultDiv.className = 'error';
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 复制HTTP头部格式的cookie值
|
||||
copyAllButton.addEventListener('click', function() {
|
||||
chrome.tabs.query({active: true, currentWindow: true}, function(tabs) {
|
||||
const currentTab = tabs[0];
|
||||
const url = new URL(currentTab.url);
|
||||
const exactDomain = url.hostname;
|
||||
|
||||
// 检查是否是网易相关域名
|
||||
const isNeteaseHost = exactDomain.includes('netease.com') || exactDomain.includes('breeze');
|
||||
|
||||
// 获取域名及其父域名
|
||||
const domains = getDomainAndParents(exactDomain);
|
||||
|
||||
// 如果是网易域名,加入特殊的网易域名
|
||||
if (isNeteaseHost) {
|
||||
domains.push('netease.com');
|
||||
domains.push('.netease.com');
|
||||
domains.push('gameyw.netease.com');
|
||||
domains.push('opd.netease.com');
|
||||
domains.push('breeze.opd.netease.com');
|
||||
domains.push('breeze.gameyw.netease.com');
|
||||
}
|
||||
|
||||
// 为每个域名创建一个Promise,获取该域名下的所有cookie
|
||||
const cookiePromises = domains.map(domain => {
|
||||
return new Promise((resolve) => {
|
||||
chrome.cookies.getAll({domain: domain}, (cookies) => {
|
||||
resolve(cookies || []);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 使用注入脚本获取页面上的document.cookie
|
||||
chrome.scripting.executeScript({
|
||||
target: {tabId: tabs[0].id},
|
||||
func: function() {
|
||||
return document.cookie;
|
||||
}
|
||||
}).then(docCookieResult => {
|
||||
const docCookies = docCookieResult[0].result ?
|
||||
docCookieResult[0].result.split(';').map(cookie => cookie.trim()) : [];
|
||||
|
||||
// 等待所有cookie获取完成
|
||||
Promise.all(cookiePromises).then(cookiesArrays => {
|
||||
// 合并并去重所有cookie
|
||||
const cookieMap = new Map();
|
||||
|
||||
// 处理Chrome API获取的cookie
|
||||
cookiesArrays.forEach(cookies => {
|
||||
cookies.forEach(cookie => {
|
||||
cookieMap.set(cookie.name, cookie.value);
|
||||
});
|
||||
});
|
||||
|
||||
// 处理document.cookie获取的cookie
|
||||
docCookies.forEach(cookieStr => {
|
||||
const parts = cookieStr.split('=');
|
||||
if (parts.length >= 2) {
|
||||
const name = parts[0].trim();
|
||||
const value = parts.slice(1).join('=');
|
||||
cookieMap.set(name, value);
|
||||
}
|
||||
});
|
||||
|
||||
// 如果是网易域名,确保包含SESSION等重要cookie
|
||||
const importantCookieNames = [
|
||||
'SESSION', 'sensorsdata2015jssdkcross', 'Hm_lvt_', '_ga', 'COSPREAD_SESSIONID',
|
||||
'identity', 'csrftoken', 'accessToken', 'refreshToken', 'sessionid'
|
||||
];
|
||||
|
||||
// 获取所有cookie项
|
||||
let cookieStrings = [];
|
||||
|
||||
if (isNeteaseHost) {
|
||||
// 网易域名特殊处理:确保SESSION在结果的最前面
|
||||
let sessionCookie = null;
|
||||
let importantCookies = [];
|
||||
let otherCookies = [];
|
||||
|
||||
// 分类处理cookie
|
||||
for (const [name, value] of cookieMap.entries()) {
|
||||
if (name.toUpperCase() === 'SESSION') {
|
||||
sessionCookie = `${name}=${value}`;
|
||||
} else if (importantCookieNames.some(key => name.includes(key))) {
|
||||
importantCookies.push(`${name}=${value}`);
|
||||
} else {
|
||||
otherCookies.push(`${name}=${value}`);
|
||||
}
|
||||
}
|
||||
|
||||
// 按优先级组装cookie字符串
|
||||
if (sessionCookie) {
|
||||
cookieStrings.push(sessionCookie);
|
||||
}
|
||||
cookieStrings = cookieStrings.concat(importantCookies);
|
||||
|
||||
// 如果没有其他重要cookie,考虑添加部分普通cookie
|
||||
if (cookieStrings.length < 3 && otherCookies.length > 0) {
|
||||
cookieStrings = cookieStrings.concat(otherCookies.slice(0, 5));
|
||||
}
|
||||
} else {
|
||||
// 非网易域名,使用所有cookie
|
||||
cookieStrings = Array.from(cookieMap.entries()).map(([name, value]) => `${name}=${value}`);
|
||||
}
|
||||
|
||||
// 格式化为HTTP头格式
|
||||
const headerCookieFormat = cookieStrings.join('; ');
|
||||
|
||||
// 复制到剪贴板
|
||||
navigator.clipboard.writeText(headerCookieFormat)
|
||||
.then(() => {
|
||||
resultDiv.textContent = '已复制Header格式Cookie';
|
||||
resultDiv.className = 'success';
|
||||
|
||||
// 显示cookie数量
|
||||
const cookieCount = cookieStrings.length;
|
||||
resultDiv.textContent += ` (共${cookieCount}项)`;
|
||||
|
||||
// 预览
|
||||
if (cookieStrings.length > 0) {
|
||||
const preview = headerCookieFormat.length > 80 ?
|
||||
headerCookieFormat.substring(0, 80) + '...' :
|
||||
headerCookieFormat;
|
||||
resultDiv.textContent += '\n预览: ' + preview;
|
||||
}
|
||||
})
|
||||
.catch(err => {
|
||||
resultDiv.textContent = '复制失败: ' + err;
|
||||
resultDiv.className = 'error';
|
||||
});
|
||||
});
|
||||
}).catch(err => {
|
||||
resultDiv.textContent = '脚本执行失败: ' + err.message;
|
||||
resultDiv.className = 'error';
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// 辅助函数:获取域名及其父域名
|
||||
// 例如:breeze.opd.netease.com -> ['breeze.opd.netease.com', 'opd.netease.com', 'netease.com']
|
||||
function getDomainAndParents(domain) {
|
||||
const parts = domain.split('.');
|
||||
const domains = [];
|
||||
|
||||
// 添加完整域名
|
||||
domains.push(domain);
|
||||
|
||||
// 添加父域名
|
||||
for (let i = 1; i < parts.length - 1; i++) {
|
||||
domains.push(parts.slice(i).join('.'));
|
||||
}
|
||||
|
||||
return domains;
|
||||
}
|
||||
});
|
Loading…
x
Reference in New Issue
Block a user