File size: 1,989 Bytes
110d062
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
import { Puppeteer } from "https://deno.land/x/[email protected]/mod.ts";

let browser: any;

const initBrowser = async () => {
  const puppeteer = new Puppeteer({
    browserPath: '/app/chrome/chrome-linux64/chrome',
  });
  
  browser = await puppeteer.launch({
    headless: true,
    args: [
      "--no-sandbox",
      "--disable-setuid-sandbox"
    ]
  });
};

initBrowser();

Deno.serve({ port: 7860 }, async (req: Request) => {
  const url = new URL(req.url);
  const pathname = url.pathname;
  const searchParams = url.searchParams;

  if (pathname === "/screenshot" && req.method === "GET") {
    const targetUrl = searchParams.get("url");
    if (!targetUrl) {
      return new Response("Missing url parameter", { status: 400 });
    }

    let page;
    try {
      if (!browser) {
        await initBrowser();
      }

      page = await browser.newPage();
      await page.setViewport({ width: 1920, height: 1080 });

      await page.goto(targetUrl, {
        waitUntil: 'networkidle0',
        timeout: 30000
      });

      const screenshotBuffer = await page.screenshot();
      
      if (page) {
        await page.close();
      }

      return new Response(screenshotBuffer, {
        headers: { "Content-Type": "image/png" },
        status: 200,
      });
    } catch (error) {
      console.error("Error taking screenshot:", error);
      if (page) {
        try {
          await page.close();
        } catch (e) {
          // 忽略关闭页面时的错误
        }
      }
      return new Response("Error taking screenshot", { status: 500 });
    }
  } else if (pathname === "/") {
    const htmlFilePath = "/app/index.html";
    const htmlContent = await Deno.readTextFile(htmlFilePath);
    return new Response(htmlContent, {
      headers: { "Content-Type": "text/html" },
      status: 200,
    });
  } else {
    return new Response("Not Found", { status: 404 });
  }
});