You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Playwright自定义配置中extraHTTPHeaders未生效,请求报JSON解析错误

Playwright配置extraHTTPHeaders后请求报错SyntaxError: Unexpected end of JSON input

问题描述

我在Playwright的自定义配置文件api.config.js中配置了extraHTTPHeaders,包含携带环境变量ACCESS_TOKEN的Authorization头,以及Content-Type: application/json,期望请求自动带上这些头部。通过命令npx playwright test --config=api.config.js运行测试,测试文件里在beforeAll阶段调用getToken函数获取令牌,之后用request.post发送GraphQL请求,但执行const responseBody = await response.json();时出现SyntaxError: Unexpected end of JSON input错误。想问这种读取配置头部的方式是否正确?错误原因是什么?

配置代码(api.config.js)

const { devices, chromium } = require('@playwright/test');
// const { getToken } = require("./helper");
use: {
    /* Maximum time each action such as `click()` can take. Defaults to 0 (no limit). */
    actionTimeout: 0,
    // headless: true,
    /* Base URL to use in actions like `await page.goto('/')`. */
    baseURL: 'https://connect.dev.morinc.com/api/eds',
    extraHTTPHeaders: {
      Authorization: `Bearer ${process.env.ACCESS_TOKEN}`,
      'Content-Type': "application/json"
    },
    /* Collect trace when retrying the failed test. */
    trace: 'on-first-retry',
  },

测试代码

const { getToken } = require("../../auth0");
import { faker } from '@faker-js/faker';
const { entityTypes } = require("../../global.js");

test.beforeAll(async() => {
  await getToken();
})

test.describe('Create Entity', async() => { 
  test("Create an entity", async ({baseURL, request}) => {
    const requestBody = {
      data: {
        query: `
          mutation CreateEntity($name: String!, $type: EntityType, $active: Boolean, $identifiers: [String]) {
            createEntity(name: $name, type: $type, active: $active, identifiers: $identifiers)  {
              name
              type
              active
              id
              identifiers
              items
          }
        }`,
        variables: {
          name: faker.name.fullName(),
          type: entityTypes.corporate,
          active: true,
          identifiers: []
        }
      }
      };
    const response = await request.post(baseURL, requestBody);
    const responseBody = await response.json();
    //Assertions
    expect(response.status()).toBe(200);
    expect(responseBody.data.createEntity.name).toBe(requestBody.data.variables.name);
    expect(responseBody.data.createEntity.type).toBe(requestBody.data.variables.type);
    expect(responseBody.data.createEntity.active).toBeTruthy();
    expect(responseBody.data.createEntity.id).toBeTruthy();
    expect(responseBody.data.createEntity.identifiers).toHaveLength(0);
    expect(responseBody.data.createEntity.items).toBe(null);
  });
}); 

getToken函数代码

require("dotenv").config({path: ".env.dev"});
let auth0Credentials = JSON.parse(process.env.AUTH0_CONFIG)
let userCredentials = JSON.parse(process.env.USERS_CREDENTIALS)


async function getToken() {
  const tokenExpiration = process.env.ACCESS_TOKEN_EXPIRATION;
  const storedToken = process.env.ACCESS_TOKEN;
  if (
    storedToken &&
    tokenExpiration &&
    new Date(tokenExpiration) > new Date()
  ) {
    return storedToken;
  }
  const credentials = {
    client_id: auth0Credentials.client_id,
    client_secret: auth0Credentials.client_secret,
    audience: auth0Credentials.audience,
    grant_type: auth0Credentials.grant_type,
    username: userCredentials.q4admin,
    password: userCredentials.password,
  };

  const url = auth0Credentials.oauthURL;

  const options = {
    method: "POST",
    headers: {
      "Content-Type": "application/json",
    },
    body: JSON.stringify(credentials),
  };
  
  const response = await fetch(url, options);
  const json = await response.json();
  const expiresIn = json.expires_in || 0;
  const accessToken = json.access_token || "";

  process.env.ACCESS_TOKEN_EXPIRATION = new Date(Date.now() + expiresIn * 1000).toISOString();
  process.env.ACCESS_TOKEN = accessToken;
  return accessToken;
}

module.exports = {getToken}

问题分析与解决

1. 配置头部的方式不正确

Playwright配置文件在测试进程启动时就完成解析加载,而getToken是在测试的beforeAll阶段才执行,此时process.env.ACCESS_TOKEN还未被赋值,导致extraHTTPHeaders里的Authorization头实际是Bearer undefined,属于无效鉴权信息。服务器收到这类请求后通常返回401未授权响应,且响应内容不是JSON格式(可能是空白、HTML错误页或纯文本提示),最终引发response.json()解析错误。

2. 请求体格式错误

测试代码中request.post直接传入requestBody对象,但Playwright的request.post要求请求体放在data字段中。直接传对象会导致请求体格式异常,服务器无法解析请求,返回非JSON响应,同样触发解析错误。

正确的解决步骤

步骤一:修正请求发送格式

将request.post调用改为正确格式,把GraphQL请求体放在data字段内:

const response = await request.post(baseURL, {
  data: requestBody.data // 仅传递GraphQL所需的query和variables部分
});

步骤二:动态设置请求头

放弃配置文件中的静态extraHTTPHeaders配置,改为在beforeAll获取token后给request上下文动态设置全局默认请求头:

test.beforeAll(async ({ request }) => {
  const token = await getToken();
  // 给当前request上下文设置全局默认请求头
  await request.context().setExtraHTTPHeaders({
    Authorization: `Bearer ${token}`,
    'Content-Type': 'application/json'
  });
});

这样后续所有request发起的请求都会自动携带有效头部。

步骤三:调试辅助

在解析响应JSON前,先打印响应状态和文本,快速定位问题:

console.log('响应状态码:', response.status());
console.log('响应内容:', await response.text());

内容的提问来源于stack exchange,提问作者vormier

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 19:47:00