Chrome 在Puppeteer中如何发送POST请求?

o2rvlv0m  于 2023-02-27  发布在  Go
关注(0)|答案(4)|浏览(649)

我使用以下代码发送GET请求:

(async() => {
    const browser = await puppeteer.launch();
    const page = await browser.newPage();
    await page.goto('https://www.example.com/search');
    const data = await page.content();
    browser.close();
    res.send(data);
})();

如何发送POST请求?

hl0ma9xz

hl0ma9xz1#

正确的“顺序”可能是一个挑战,文档中没有那么多的例子......在存储库的example文件夹中有一些有趣的项目,你一定要看一看。
https://github.com/GoogleChrome/puppeteer/tree/main/examples
这是一个例子将以下内容放入异步块中:

// Create browser instance, and give it a first tab
const browser = await puppeteer.launch();
const page = await browser.newPage();

// Allows you to intercept a request; must appear before
// your first page.goto()
await page.setRequestInterception(true);

// Request intercept handler... will be triggered with 
// each page.goto() statement
page.on('request', interceptedRequest => {

    // Here, is where you change the request method and 
    // add your post data
    var data = {
        'method': 'POST',
        'postData': 'paramFoo=valueBar&paramThis=valueThat'
    };

    // Request modified... finish sending! 
    interceptedRequest.continue(data);
});

// Navigate, trigger the intercept, and resolve the response
const response = await page.goto('https://www.example.com/search');     
const responseBody = await response.text();
console.log(responseBody);

// Close the browser - done! 
await browser.close();
4urapxun

4urapxun2#

setRequestInterception'request'事件的工作方式有一个怪癖。一旦激活,Puppeteer将发送POST数据到页面上的每个资源,而不仅仅是最初请求的页面。我遇到了一个问题,即一旦我在Puppeteer中添加POST数据,所有页面资源(脚本、CSS)都无法加载。
由于我只想将POST数据应用于第一个请求,所以下面的代码对我很有效:

// Used for serializing POST parameters from an object
const querystring = require('querystring');

// ...

const browser = await puppeteer.launch();
const page = await browser.newPage();

let postData = {a: 1, b: 2};

await page.setRequestInterception(true);

page.once('request', request => {
    var data = {
        'method': 'POST',
        'postData': querystring.stringify(postData),
        'headers': {
            ...request.headers(),
            'Content-Type': 'application/x-www-form-urlencoded'
        },
    };

    request.continue(data);

    // Immediately disable setRequestInterception, or all other requests will hang
    page.setRequestInterception(false);
});

const response = await page.goto('https://www.example.com/');
bxpogfeg

bxpogfeg3#

下面是Puppeteer 2.0.0的完整示例:

const puppeteer = require("puppeteer");
    const devices = require("puppeteer/DeviceDescriptors");

    async function main() {
      const browser = await puppeteer.launch({
        args: ["--enable-features=NetworkService", "--no-sandbox"],
        ignoreHTTPSErrors: true
      });
      const page = await browser.newPage();

      await page.setRequestInterception(true);

      page.once("request", interceptedRequest => {
        interceptedRequest.continue({
          method: "POST",
          postData: "foo=FOO&bar=BAR",
          headers: {
            ...interceptedRequest.headers(),
            "Content-Type": "application/x-www-form-urlencoded"
          }
        });
      });

      const response = await page.goto("https://postman-echo.com/post");

      console.log({
        url: response.url(),
        statusCode: response.status(),
        body: await response.text()
      });

      await browser.close();
    }

    main();

请注意,如果选中response.request().method(),它将不会更新(仍然是GET)

1mrurvl1

1mrurvl14#

您可以使用Page.evaluate() method在浏览器中运行Fetch API。例如:

const postResponse = await page.evaluate( async (param1, param2, param3) => {
  const response = await fetch("https://www.example.com/add", {
    "headers": {
      "content-type": "application/x-www-form-urlencoded; charset=UTF-8"
    },
    "body": `param1=${param1}&param2=${param2}&param3=${param3}`,
    "method": "POST"
  });
  const data = await response.json();
  return data;
}, param1, param2, param3);

相关问题