在iphone和ipad上很多公益站点击"使用 LinuxDO 继续"后不会跳转登录。用codex排查了一下写了个小脚本,ios可以下个stay或者类似的软件。测试了几个网站结果都OK。
刚看到有类似的讨论 为什么ios的safari浏览器用不了linuxdo的第三方登录? - #10,来自 pluto233
不过之前的解决方案需要更改Safari设置,这个脚本可以保留原来的设置。
// ==UserScript==
// @name LinuxDO OAuth Popup Fix for iOS
// @namespace https://linux.do/
// @version 1.0.0
// @description 修复 iOS/Safari 上 LinuxDO OAuth 因异步 window.open 被拦截而无法跳转的问题
// @author Codex
// @match http://*/*
// @match https://*/*
// @run-at document-start
// @grant none
// ==/UserScript==
(function () {
'use strict';
const ONLY_IOS = true;
const MAX_GESTURE_AGE_MS = 3000;
const DEBUG = false;
let lastGesture = { matched: false, at: 0, text: '', href: '' };
function log(...args) {
if (DEBUG) console.info('[LinuxDO OAuth Popup Fix]', ...args);
}
function isIOSWebKit() {
const ua = navigator.userAgent || '';
const platform = navigator.platform || '';
const touchMac = platform === 'MacIntel' && navigator.maxTouchPoints > 1;
const appleMobile = /iPhone|iPad|iPod/i.test(ua) || touchMac;
return appleMobile && /AppleWebKit/i.test(ua);
}
function normalize(value) {
return String(value || '')
.toLowerCase()
.replace(/\s+/g, '')
.trim();
}
function isLinuxDOAuthUrl(rawUrl) {
if (!rawUrl) return false;
try {
const url = new URL(rawUrl, location.href);
const host = url.hostname.toLowerCase();
const path = url.pathname.toLowerCase();
if (host !== 'connect.linux.do' && host !== 'linux.do') return false;
if (host === 'connect.linux.do' && path.startsWith('/oauth2/authorize')) return true;
if (host === 'linux.do' && path.includes('/auth/')) return true;
return false;
} catch {
return false;
}
}
function classifyLinuxDOTrigger(target) {
if (!target) return { matched: false, text: '', href: '' };
const text = target.textContent || '';
const href =
target.getAttribute?.('href') ||
target.dataset?.href ||
target.getAttribute?.('data-href') ||
'';
const ariaLabel = target.getAttribute?.('aria-label') || '';
const title = target.getAttribute?.('title') || '';
const className = typeof target.className === 'string' ? target.className : '';
const combined = normalize([text, href, ariaLabel, title, className].filter(Boolean).join(' '));
const mentionsLinuxDO =
combined.includes('linuxdo') ||
combined.includes('linux.do') ||
isLinuxDOAuthUrl(href);
const actionWords = [
'继续',
'登录',
'登入',
'授权',
'绑定',
'continue',
'login',
'signin',
'sign-in',
'oauth',
'authorize',
'connect',
'bind',
'auth',
];
const hasActionWord =
actionWords.some((word) => combined.includes(normalize(word))) || isLinuxDOAuthUrl(href);
return { matched: Boolean(mentionsLinuxDO && hasActionWord), text, href };
}
function captureGesture(event) {
const el = event.target?.closest?.('button, a, [role="button"], [onclick], input[type="button"], input[type="submit"]');
const result = classifyLinuxDOTrigger(el);
lastGesture = {
...result,
at: Date.now(),
};
if (result.matched) log('captured gesture', result);
}
function shouldConvertPopupToRedirect(rawUrl) {
if (!isLinuxDOAuthUrl(rawUrl)) return false;
if (!lastGesture.matched) return false;
return Date.now() - lastGesture.at <= MAX_GESTURE_AGE_MS;
}
if (ONLY_IOS && !isIOSWebKit()) {
return;
}
document.addEventListener('pointerdown', captureGesture, true);
document.addEventListener('touchstart', captureGesture, true);
document.addEventListener('click', captureGesture, true);
const realOpen = window.open.bind(window);
window.open = function patchedOpen(url, target, features) {
if (shouldConvertPopupToRedirect(url)) {
log('convert popup to same-tab redirect', { url, target, features, lastGesture });
location.assign(String(url));
return window;
}
return realOpen(url, target, features);
};
})();
linuxdo-oauth-popup-fix.user.js.zip (1.7 KB)
1 个帖子 - 1 位参与者