Sleazy Fork is available in English.
为漫画站增加双页阅读、翻译等优化体验的增强功能。百合会(记录阅读历史、自动签到等)、百合会新站、E-Hentai(关联外站、快捷收藏、标签染色、识别广告页等)、nhentai(彻底屏蔽漫画、无限滚动)、Yurifans(自动签到)、拷贝漫画(copymanga)(显示最后阅读记录、解锁隐藏漫画)、再漫画、漫画柜(manhuagui)、动漫屋(dm5)、mangabz、komiic、無限動漫、绅士漫画(wnacg)、禁漫天堂、NoyAcg、熱辣漫畫、hanime1、hitomi、hdoujin、SchaleNetwork、nude-moon、HentaiZap、IMHentai、HentaiEra、HentaiEnvy、MangaDex、welovemanga、kisslove(klz9)、kemono、nekohouse、Pixiv、明日方舟泰拉记事社、最前線、芸能ヌード、Tachidesk、LANraragi
附议
翻了下过往评论,作者今年现实比较忙碌,再漫画这个问题是今天才出现,应该是网页改版/接口更新的原因。
我让ai辅助改了下,替换掉原代码从“ // #漫画站(中文)[再漫画](https://manhua.zaimanhua.com/)”下面三个case的部分即可应急使用。
当然更稳健的更新,还得期待作者更优雅的更新:
// #漫画站(中文)[再漫画](https://manhua.zaimanhua.com/)
// test: https://manhua.zaimanhua.com/view/heimaohemonvdeketang/64175/133789
case 'www.zaimanhua.com':
case 'manhua.zaimanhua.com':
case 'm.zaimanhua.com':
{
const isMobile = location.host === 'm.zaimanhua.com';
const apiBase = isMobile ? 'https://manhua.zaimanhua.com' : '';
const apiReferer = isMobile ? 'https://manhua.zaimanhua.com/' : location.href;
const getZaimanhuaAuthHeaders = () => {
let token = '';
try {
// 从 Cookie 读取
token =
document.cookie
.split(';')
.map(c => c.trim())
.find(c =>
/^(token|authorization|access_token|jwt|zm_token|zaimanhua_token|zaimanhua_web_token)=/.test(c)
)
?.split('=')
.slice(1)
.join('=') || '';
// 兜底从 localStorage / sessionStorage 读取
if (!token) {
const win = typeof unsafeWindow !== 'undefined' ? unsafeWindow : window;
for (const storage of [win.localStorage, win.sessionStorage].filter(Boolean)) {
token =
Object.keys(storage)
.filter(key =>
/token|authorization|access_token|jwt|zm_token|zaimanhua/i.test(key)
)
.map(key => storage.getItem(key))
.find(Boolean) || '';
if (token) break;
}
}
} catch (error) {
console.warn('zaiManHua: 读取本地 token 失败', error);
}
token = String(token || '').trim();
try {
token = decodeURIComponent(token);
} catch {
// 解码失败就保持原样
}
token = token.replace(/^["']+|["']+$/g, '');
// 如果 token 被存成了 JSON 字符串,尝试解析
try {
const parsed = JSON.parse(token);
if (typeof parsed === 'string') {
token = parsed;
} else if (parsed && typeof parsed === 'object') {
token =
parsed.token ||
parsed.access_token ||
parsed.authorization ||
parsed.jwt ||
parsed?.data?.token ||
'';
}
} catch {
// 不是 JSON 就保持原样
}
if (!token) return {};
return {
Authorization: /^bearer\s+/i.test(token) ? token : `Bearer ${token}`
};
};
const zaiRequest = async (url, silent = false) => {
const res = await main.request(apiBase + url, {
responseType: 'json',
headers: {
Accept: 'application/json, text/plain, */*',
Referer: apiReferer,
...getZaimanhuaAuthHeaders()
}
});
const body = res?.response ?? {};
if (body.errno && Number(body.errno) !== 0) {
if (!silent) {
main.toast.error(`${helper.t('alert.comic_load_error')}: ${body.errmsg}`, {
throw: true
});
}
throw new Error(body.errmsg || helper.t('alert.comic_load_error'));
}
return body?.data ?? {};
};
const getChapterInfo = (comicId, chapterId, silent = false) =>
zaiRequest(
`/api/v1/comic2/chapter/detail?comic_id=${comicId}&chapter_id=${chapterId}`,
silent
).then(data => data?.chapterInfo ?? {});
const getComicInfoByPy = (comicPy, silent = false) =>
zaiRequest(
`/api/v1/comic2/comic/detail?comic_py=${encodeURIComponent(comicPy)}`,
silent
).then(data => data?.comicInfo ?? {});
const getComicInfoById = (comicId, silent = false) =>
zaiRequest(
`/api/v1/comic2/comic/detail?id=${comicId}`,
silent
).then(data => data?.comicInfo ?? {});
const getSortedChapters = (comicInfo, chapterId) => {
const groups = Array.isArray(comicInfo?.chapterList)
? comicInfo.chapterList
: [];
const group =
groups.find(
g =>
Array.isArray(g?.data) &&
g.data.some(ch => Number(ch?.chapter_id) === Number(chapterId))
) ?? groups[0];
const chapters = Array.isArray(group?.data) ? [...group.data] : [];
return chapters.sort(
(a, b) =>
(Number(a?.chapter_order) || 0) - (Number(b?.chapter_order) || 0)
);
};
const extractImgList = chapterInfo => {
let imgList = chapterInfo?.page_url_hd;
if (!Array.isArray(imgList) || imgList.length === 0) {
imgList = chapterInfo?.page_url;
}
if (!Array.isArray(imgList)) {
return [];
}
return imgList.filter(url => Boolean(url));
};
if (isMobile) {
options = {
name: 'zaiManHua',
async getImgList({ setState }) {
const urlParams = new URLSearchParams(location.search);
const comicId = Number(urlParams.get('comic_id'));
const chapterId = Number(urlParams.get('chapter_id'));
if (!comicId || !chapterId) {
throw new Error(helper.t('site.changed_load_failed'));
}
// 获取上一话 / 下一话
try {
const comicInfo = await getComicInfoById(comicId, true);
const chapters = getSortedChapters(comicInfo, chapterId);
const index = chapters.findIndex(
ch => Number(ch?.chapter_id) === Number(chapterId)
);
setState('manga', {
onPrev:
index > 0
? () =>
location.assign(
`/pages/comic/page?comic_id=${comicId}&chapter_id=${
chapters[index - 1].chapter_id
}`
)
: undefined,
onNext:
index !== -1 && index + 1 < chapters.length
? () =>
location.assign(
`/pages/comic/page?comic_id=${comicId}&chapter_id=${
chapters[index + 1].chapter_id
}`
)
: undefined
});
} catch (error) {
console.warn('zaiManHua mobile: 获取上/下话失败', error);
}
const chapterInfo = await getChapterInfo(comicId, chapterId);
const imgList = extractImgList(chapterInfo);
if (imgList.length === 0) {
throw new Error(helper.t('alert.comic_load_error'));
}
return imgList;
},
SPA: {
isMangaPage: () => location.pathname === '/pages/comic/page'
}
};
} else {
options = {
name: 'zaiManHua',
wait: () =>
Boolean(helper.querySelector('.scrollbar-demo-item')) ||
location.pathname.startsWith('/view/'),
async getImgList({ setState }) {
const match = location.pathname.match(/^\/view\/([^/]+)\/(\d+)\/(\d+)/);
if (!match) throw new Error(helper.t('site.changed_load_failed'));
const comicPy = decodeURIComponent(match[1]);
const comicId = Number(match[2]);
const chapterId = Number(match[3]);
// 获取上一话 / 下一话
try {
const comicInfo = await getComicInfoByPy(comicPy, true);
const chapters = getSortedChapters(comicInfo, chapterId);
const index = chapters.findIndex(
ch => Number(ch?.chapter_id) === Number(chapterId)
);
const base = `/view/${encodeURIComponent(comicPy)}/${comicId}`;
setState('manga', {
onPrev:
index > 0
? () =>
location.assign(`${base}/${chapters[index - 1].chapter_id}`)
: undefined,
onNext:
index !== -1 && index + 1 < chapters.length
? () =>
location.assign(`${base}/${chapters[index + 1].chapter_id}`)
: undefined
});
} catch (error) {
console.warn('zaiManHua: 获取上/下话失败', error);
}
const chapterInfo = await getChapterInfo(comicId, chapterId);
const imgList = extractImgList(chapterInfo);
if (imgList.length === 0) {
throw new Error(helper.t('alert.comic_load_error'));
}
return imgList;
},
SPA: {
isMangaPage: () => location.pathname.startsWith('/view/')
}
};
}
break;
}
请问作者可以更新一下再漫画网页的代码吗?现在显示为“Cannot read properties of undefined (reading 'length')”