不是。。。为什么说油猴操作不了cookie?

2,316 阅读3分钟

前言

油猴中文网论坛,不会就可以上去po问题去问,或者搜已经解决的有没有正好是自己的需求的。

一些现成的有趣的脚本,供我们安装。

之前我们讲过——油猴插件(Tampermonkey)的相关配置文章,今天接着讲一下,用油猴去操作任何网站的cookie的相关操作。

我们要有一种思维,就是万物皆可脚本化

可能有的伙伴还不太清楚油猴是个啥?

这么说吧,油猴就是另起的一段js代码,在别人或自个儿的网站上跑另外一段逻辑的一个用户脚本管理器,就是一种浏览器扩展插件

这里介绍几个给大家轮着用,想下载哪个下哪个:

1、暴力猴:

image.png

2、篡改猴:

image.png

3、篡改猴测试版:

image.png

4、脚本猫:

image.png

image.png

当然,还有市场上还有更多类似这种的油猴插件,供我们安装。

有伙伴可能说了,给我介绍那么多个干嘛,我每个都安装吗。安装一个就可以,但是如果那个对于你的某种浏览器不起作用的时候,有备胎可选,解燃眉之急,可好☺️。

又有伙伴可能观察🔎到了,就是为啥全是篡改猴🐒这样的,所有这些猴🐒,在适用Firefox浏览器的浏览器扩展程序里边,有个叫油猴

那么Tampermonkey篡改猴,适用chromeedgesafarioperafirefox等等。

image.png

正文

接着,给大家贴一下它的官方开发文档www.tampermonkey.net/documentati…

最近有一个需求,就是:更改cookieSameSite属性,从strict改为none。这样子,就是,不同源(协议、域名、端口)的两个网站,用window.location.href或者window.open跳转之后,能保存cookie而不清空。

一般,不同源的网站,Cookie设置了SameSite=Strict,不会带上这个Cookie。所以我们就要修改范围SameSite=None, Secure,这样请求才会自动带上Cookies到后端请求接口。

接下来先用原生思路去思考一下js如何设置Cookies

原生设置Cookie:

function setCookie(name, value, days) {
    let expires = "";
    if (days) {
        const date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + (value || "") + expires + "; path=/";
}

原生获取Cookie

function getCookie(name) {
    const nameEQ = name + "=";
    const ca = document.cookie.split(';');
    for(let i = 0; i < ca.length; i++) {
        let c = ca[i];
        while (c.charAt(0) === ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) === 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
}

删除Cookie

function deleteCookie(name) {   
    document.cookie = name + '=; Path=/; Expires=Thu, 01 Jan 1970 00:00:01 GMT;';
}

直接在油猴脚本中使用document.cookie可能会遇到以下问题:

  1. 由于油猴脚本运行在沙盒环境中,某些网站的HttpOnly Cookie无法直接访问
  2. 跨域限制可能导致操作失败
  3. 某些网站设置了Secure属性,只能在HTTPS下传输

那么接下来看看在油猴中是如何操作Cookie的:

我们先用官网的操作Cookie方法 —— GM_cookie

image.png

// 设置Cookie
GM_cookie.set({
    url: 'https://example.com',
    name: 'test_cookie',
    value: 'test_value',
    domain: '.example.com',
    path: '/',
    secure: true,
    httpOnly: false,
    expirationDate: Math.floor(Date.now() / 1000) + 86400 // 1天后过期
}, function() {
    console.log('Cookie set');
});

// 获取Cookie
GM_cookie.list({
    url: 'https://example.com',
    name: 'test_cookie'
}, function(cookies) {
    console.log('Found cookies:', cookies);
});

// 删除Cookie
GM_cookie.delete({
    url: 'https://example.com',
    name: 'test_cookie'
}, function() {
    console.log('Cookie deleted');
});

但前提在脚本头部要声明权限:

// @grant        GM_cookie

案例

自动登录网站

// ==UserScript==
// @name         自动登录示例
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  自动填写并提交登录表单
// @author       You
// @match        https://example.com/login
// @grant        GM_cookie
// ==/UserScript==

(function() {
    'use strict';
    
    // 检查是否有保存的Cookie
    GM_cookie.list({url: 'https://example.com', name: 'remember_token'}, function(cookies) {
        if (cookies && cookies.length > 0) {
            // 自动提交表单
            document.querySelector('form.login-form').submit();
        } else {
            // 没有保存的Cookie,显示登录表单
            document.getElementById('username').value = 'my_username';
            document.getElementById('password').value = 'my_password';
            document.querySelector('input[type="checkbox"][name="remember"]').checked = true;
        }
    });
})();

跨域共享Cookie

// ==UserScript==
// @name         跨域Cookie共享
// @namespace    http://tampermonkey.net/
// @version      0.1
// @description  在多个相关网站间共享登录状态
// @author       You
// @match        https://*.example.com/*
// @match        https://*.example.org/*
// @grant        GM_cookie
// @grant        GM_xmlhttpRequest
// @connect      example.com
// @connect      example.org
// ==/UserScript==

(function() {
    'use strict';
    
    // 获取当前域名的Cookie
    const currentDomain = window.location.hostname;
    const isExampleCom = currentDomain.includes('example.com');
    
    if (isExampleCom) {
        // 在example.com域,检查是否有example.org的Cookie
        GM_cookie.list({url: 'https://example.org', name: 'session_id'}, function(cookies) {
            if (cookies && cookies.length > 0) {
                // 同步到当前域
                GM_cookie.set({
                    url: 'https://example.com',
                    name: 'session_id',
                    value: cookies[0].value,
                    domain: '.example.com',
                    secure: true,
                    expirationDate: cookies[0].expirationDate
                });
            }
        });
    } else {
        // 在example.org域,执行相反的操作
        // ...
    }
})();

总结

  1. 原生方法document.cookie简单直接,但在油猴中可能受限
  2. 油猴专用APIGM_cookie更强大,能处理更多复杂场景