[Regression]: APIRequestContext JSON-encodes string data for "application/json;charset=UTF-8" since 1.65 (not in release notes)

クローズ 初心者向け
#43,937 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@microsoft-playwright-automation がすでに取り組んでいます。

2026年11月5日 から。

  • #43945 @microsoft-playwright-automation による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
74/100
issue の種類
ドキュメント
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
node.js, playwright, typescript
領域
api, documentation

調査の方向性

APIRequestContext の data オプションのドキュメントと 1.65 のリリースノートから確認します。issue には更新の要望が 2 件記載されていますが、ファイルパスはありません。ドキュメントで string の本文がどう説明されているか、リリースノートで breaking changes がどう説明されているかを確認し、そのうえで JSON の Content-Type の動作を明確にし、正確なバイト列を扱う場合は Buffer に言及します。両方の更新で報告された動作が正確に反映されていれば完了です。

索引モデルが issue の本文から書いたものです。

説明

needs-triage
Version

1.65.0 (same in 1.66.0-alpha-2026-11-05). Different in 1.64.1.

Steps to reproduce
// repro.mjs — "type": "module", @playwright/test installed
import http from 'node:http';
import { request } from '@playwright/test';

const srv = http.createServer((req, res) => { let b = ''; req.on('data', c => b += c); req.on('end', () => res.end(b)); });
await new Promise(r => srv.listen(0, r));
const url = `http://127.0.0.1:${srv.address().port}/`;
const ctx = await request.newContext();

for (const ct of ['application/json', 'application/json;charset=UTF-8', 'application/json; charset=utf-8', 'Application/JSON', 'application/problem+json']) {
  const r = await ctx.post(url, { data: 'plain text', headers: { 'content-type': ct } });
  console.log(ct, '->', JSON.stringify(await r.text()));
}
await ctx.dispose(); srv.close();
Expected behavior

Either the 1.64 behavior, or the change to be listed in the release notes. In 1.64.1 only an exact application/json header made Playwright JSON-encode a string data that is not valid JSON:

application/json                -> "\"plain text\""
application/json;charset=UTF-8  -> "plain text"
application/json; charset=utf-8 -> "plain text"
Application/JSON                -> "plain text"
application/problem+json        -> "plain text"
Actual behavior

In 1.65.0 the JSON content type is matched with parameters and case-insensitively, so the string is now JSON-encoded for these headers too:

application/json                -> "\"plain text\""
application/json;charset=UTF-8  -> "\"plain text\""
application/json; charset=utf-8 -> "\"plain text\""
Application/JSON                -> "\"plain text\""
application/problem+json        -> "plain text"

A string that parses as JSON ('{"a":1}') and a Buffer are sent as is in both versions.

Additional context

The new matching looks more correct, but it silently changes the request body. It is not mentioned in the 1.65 release notes.

What broke for us:

  • Negative API tests that send a deliberately malformed JSON body as a string (data: '{"a": ' with content-type: application/json;charset=UTF-8). The server now receives a valid JSON string literal instead of a malformed document, so the test checks something else (400 "Syntax error" becomes a different response).
  • Requests signed with HMAC over the raw body string: the signature is computed over {"a": , but "{\"a\": " is sent, so the server answers 401.

Our workaround is data: Buffer.from(body).

Requests:

  1. Please add this to the 1.65 breaking changes.
  2. Please document in APIRequestContext data that a string with a JSON content type is sent as is only when it parses as JSON, and is JSON-encoded otherwise. The docs currently read as if strings are always sent as is. Buffer is the way to send exact bytes.
Environment
OS: Linux (mcr.microsoft.com/playwright:v1.65.0-noble)
Node.js: 26.13.0
@playwright/test: 1.65.0
主要言語
TypeScript
スター
99.1k
フォーク
6.8k
平均マージ
17時間 6分
マージ済み PR(30日)
306

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

microsoft/playwright のほかの issue

microsoft/playwright の issue をすべて見る

似ている issue

TypeScript の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。