fix(route/javtrailers): replace ofetch with puppeteer for API requests (#21055)

This commit is contained in:
Tony 2026-02-04 05:27:22 +08:00 committed by GitHub
parent dc68ecb875
commit d648da5549
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 44 additions and 22 deletions

View File

@ -1,8 +1,8 @@
import type { Route } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
import puppeteer from '@/utils/puppeteer';
import { baseUrl, getItem, headers, parseList } from './utils';
import { baseUrl, getItem, parseList, puppeteerFetch } from './utils';
export const route: Route = {
path: '/casts/:cast',
@ -20,19 +20,21 @@ export const route: Route = {
handler,
features: {
nsfw: true,
requirePuppeteer: true,
},
};
async function handler(ctx) {
const { cast } = ctx.req.param();
const response = await ofetch(`${baseUrl}/api/casts/${cast}?page=0`, {
headers,
});
const browser = await puppeteer();
const response = await puppeteerFetch(`${baseUrl}/api/casts/${cast}?page=0`, browser);
const list = parseList(response.videos);
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item, browser))));
await browser.close();
return {
title: `Watch ${response.cast.name} Jav Online | Japanese Adult Video - JavTrailers.com`,

View File

@ -1,8 +1,8 @@
import type { Route } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
import puppeteer from '@/utils/puppeteer';
import { baseUrl, getItem, headers, parseList } from './utils';
import { baseUrl, getItem, parseList, puppeteerFetch } from './utils';
export const route: Route = {
path: '/categories/:category',
@ -20,19 +20,21 @@ export const route: Route = {
handler,
features: {
nsfw: true,
requirePuppeteer: true,
},
};
async function handler(ctx) {
const { category } = ctx.req.param();
const response = await ofetch(`${baseUrl}/api/categories/${category}?page=0`, {
headers,
});
const browser = await puppeteer();
const response = await puppeteerFetch(`${baseUrl}/api/categories/${category}?page=0`, browser);
const list = parseList(response.videos);
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item, browser))));
await browser.close();
return {
title: `Watch ${response.category.name} Jav Online | Japanese Adult Video - JavTrailers.com`,

View File

@ -1,8 +1,8 @@
import type { Route } from '@/types';
import cache from '@/utils/cache';
import ofetch from '@/utils/ofetch';
import puppeteer from '@/utils/puppeteer';
import { baseUrl, getItem, headers, parseList } from './utils';
import { baseUrl, getItem, parseList, puppeteerFetch } from './utils';
export const route: Route = {
path: '/studios/:studio',
@ -19,19 +19,21 @@ export const route: Route = {
handler,
features: {
nsfw: true,
requirePuppeteer: true,
},
};
async function handler(ctx) {
const { studio } = ctx.req.param();
const response = await ofetch(`${baseUrl}/api/studios/${studio}?page=0`, {
headers,
});
const browser = await puppeteer();
const response = await puppeteerFetch(`${baseUrl}/api/studios/${studio}?page=0`, browser);
const list = parseList(response.videos);
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item))));
const items = await Promise.all(list.map((item) => cache.tryGet(item.link, () => getItem(item, browser))));
await browser.close();
return {
title: `${response.studio.hotDvdIds?.join(' ') ?? response.studio.name} Jav Online | Japanese Adult Video - JavTrailers.com`,

View File

@ -1,4 +1,4 @@
import ofetch from '@/utils/ofetch';
import logger from '@/utils/logger';
import { parseDate } from '@/utils/parse-date';
import { renderDescription } from './templates/description';
@ -27,11 +27,27 @@ export const parseList = (videos) =>
contentId: item.contentId,
}));
export const getItem = async (item) => {
const response = await ofetch(`${baseUrl}/api/video/${item.contentId}`, {
headers,
export const puppeteerFetch = async (url: string, browser) => {
const page = await browser.newPage();
await page.setExtraHTTPHeaders(headers);
await page.setRequestInterception(true);
page.on('request', (request) => {
request.resourceType() === 'document' ? request.continue() : request.abort();
});
logger.http(`Requesting ${url}`);
await page.goto(url, { waitUntil: 'domcontentloaded' });
const apiResponse = await page.evaluate(() => document.body.textContent || '');
const response = JSON.parse(apiResponse);
await page.close();
return response;
};
export const getItem = async (item, browser) => {
const response = await puppeteerFetch(`${baseUrl}/api/video/${item.contentId}`, browser);
const videoInfo: Video = response.video;
videoInfo.gallery = hdGallery(videoInfo.gallery);