• home > webfront > browser > Puppeteer >

    Puppeteer setCookie设置踩坑

    Author:zhoulujun Date:

    puppeteer设置cookie,在 page setcookie方法失效,需要在browser设置,但是我发现本地,Browser setCookie() 无法跨域设置cookies,也没法设置 domain 为localhost

    看官网文档:https://pptr.cn/guides/cookies

    localhost的坑

    puppeteer设置cookie,在 page.setcookie方法失效,需要在browser设置,官方文档如下:

    https://pptr.dev/api/puppeteer.browser.setcookie

    await browser.setCookie(...cookiesArr)

    但是我发现,Browser.setCookie() 无法跨域设置cookies,也没法设置 domain 为localhost

    而且在本地开发,测试域名基本为localhost,才能调试


    这个时候,只有把测试域名换为127.0.0.1

    或者把设置puppeteer的CSP策略

    cookies属性的坑

    cookies属性有很多,但是官方并没有说明有哪些是必填属性。

    比如domain是必填项,但是官方表格是可选项!

    每个cookie,必填name、value、domain

    Property

    Modifiers

    Type

    Description

    Default

    domain

    optional

    string

    Cookie domain.


    expires

    optional

    number

    Cookie expiration date, session cookie if not set


    httpOnly

    optional

    boolean

    True if cookie is http-only.


    name

    string

    Cookie name.


    partitionKey

    optional

    CookiePartitionKey | string

    Cookie partition key. In Chrome, it matches the top-level site the partitioned cookie is available in. In Firefox, it matches the source origin (https://w3c.github.io/webdriver-bidi/\#type-storage-PartitionKey).


    path

    optional

    string

    Cookie path.


    priority

    optional

    CookiePriority

    Cookie Priority. Supported only in Chrome.


    sameParty

    optional

    boolean

    True if cookie is SameParty. Supported only in Chrome.


    sameSite

    optional

    CookieSameSite

    Cookie SameSite type.


    secure

    optional

    boolean

    True if cookie is secure.


    sourceScheme

    optional

    CookieSourceScheme

    Cookie source scheme type. Supported only in Chrome.


    url

    optional

    string

    The request-URI to associate with the setting of the cookie. This value can affect the default domain, path, and source scheme values of the created cookie.


    value

    string

    Cookie value.


    domain标识指定了哪些主机可以访问该Cookie的域名。如果设置为“.google.com”,则所有以“google.com”结尾的域名都可以访问该Cookie。注意第一个字符必须为“.”  如果是ip 端口访问

    默认是不同端口可共享,注:端口和域无关,也就是说Cookie的域是不包括端口的,这里不要带上端口,都在浏览器无法写入cookie

    Cookie的生命周期

    情况下,Cookie的生命周期是Session级别(会话级别)。若想用Cookie进行状态保存、资源共享,服务端一般都会给其设置一个过期时间maxAge,短则1小时、1天,长则1星期、1个月甚至永久,这就是Cookie的生命(周期)。Cookie的存储形式,根据其生命周期的不同而不同。这由maxAge属性决定,共有这三种情况:

    • maxAge > 0:cookie不仅内存里有,还会持久化到硬盘,也叫持久Cookie。这样的话即使你关机重启(甚至过几天再访问),这个cookie依旧存在,请求时依旧会携带

    • maxAge < 0:一般值为-1,也就临时Cookie。该Cookie只在内存中有(如session级别),一旦管理浏览器此Cookie将不复存在。值得注意的是:若使用无痕模式访问也是不会携带此Cookie的哟

    • maxAge = 0:内存中没有,硬盘中也没有了,也就立即删除Cookie。此种case存在的唯一目的:服务浏览器可能的已存在的cookie,让其立马失效(消失)

    请注意maxAge<0(负数)和maxAge=0的区别。前者会存在于内存,只有关闭浏览器or重启才失效;后者是立即删除

    跨域Cookie共享的三要素

    首先确保服务端能正确的在响应中有Set-Cookie响应头,这由Access-Control-Allow-Credentials: true来保证。因此服务端只需要做多加这一步即可:

    resp.setHeader("Access-Control-Allow-Credentials", "true");

    Access-Control-Allow-Credentials该头是可选的,是个bool值,它若为true就有两个作用:

    • 在跨域请求的响应中允许Set-Cookie响应头
      浏览器收到响应后,浏览器根据此头判断是否让自己的withCredentials属性生效

    • 第二个要素:XMLHttpRequest对象的withCredentials属性。当异步对象设置了withCredentials=true时,浏览器会保留下响应的Cookie等信息,并且下次发送请求时将其携带。因此要指示浏览器存储Cookie并且每次跨域请求都携带,仅需加上此参数即可:

    以上两个要素完成后,影响“结果”的还有最后一个要素。

    服务端的Access-Control-Allow-Origin这个响应头的值不能是通配符*,而只能是具体的值。否则出现报错:

    换句话讲:浏览器端跨域请求对象一旦开启withCredentials=true属性,服务端跨域Origin将不能再用*通配符,否则CORS error!

    三要素都满足(Access-Control-Allow-Credentials:true; Access-Control-Allow-Origin:http://localhost:63342; withCredentials=true)


    劫持xhr,手动注入cookie

    这个是笨办法,但是特别好用

    await page.setRequestInterception(true)
    page.on('request'(req) => {
      if (req.resourceType() === 'xhr') {
        const headers = req.headers()
        const reqCookies = headers.cookie
        cookiesArr.forEach((name) => {
          if (cookies[name] && !reqCookies?.includes(`${name}=`)) {
            if (!reqCookies.length || reqCookies.endsWith(';')) {
              headers.cookie += ${name}=${cookies[name]};`
            } else {
              headers.cookie += `; ${name}=${cookies[name]}`
            }
          }
        })
        req.continue({ headers })
      } else {
        req.continue()
      }
    })







    转载本站文章《Puppeteer setCookie设置踩坑》,
    请注明出处:https://www.zhoulujun.cn/html/webfront/browser/Puppeteer/9432.html

    TOP