这是一个使用 cURL 的批处理请求的示例:
curl -d '
--Batch
POST /v1/records:queryRecord?key=YOUR_API_KEY HTTP/1.1
Content-ID: item1
Content-Type: application/json
{"origin":"https://example.com", "metrics": ["first_contentful_paint"]}
--Batch
POST /v1/records:queryRecord?key=YOUR_API_KEY HTTP/1.1
Content-ID: item2
Content-Type: application/json
{"url":"https://example.com/", "metrics": ["first_contentful_paint"]}
--Batch--
' -H 'Content-Type: multipart/mixed; boundary="Batch"' -X POST -s https://chromeuxreport.googleapis.com/batch/ -v
响应如下所示:
--batch_R4dQQd20Vo_-lf91w1QTFvMinqZc7Zyj
Content-Type: application/http
Content-ID: response-item1
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
"record": {
"key": {
"origin": "https://example.com"
},
"metrics": {
"first_contentful_paint": {
"histogram": [
{
"start": 0,
"end": 1000,
"density": 0.53746873436718867
},
{
"start": 1000,
"end": 3000,
"density": 0.39049524762381554
},
{
"start": 3000,
"density": 0.072036018009005318
}
],
"percentiles": {
"p75": 1748
}
}
}
}
}
--batch_R4dQQd20Vo_-lf91w1QTFvMinqZc7Zyj
Content-Type: application/http
Content-ID: response-item2
HTTP/1.1 200 OK
Content-Type: application/json; charset=UTF-8
Vary: Origin
Vary: X-Origin
Vary: Referer
{
"record": {
"key": {
"url": "https://example.com/"
},
"metrics": {
"first_contentful_paint": {
"histogram": [
{
"start": 0,
"end": 1000,
"density": 0.5311186712027276
},
{
"start": 1000,
"end": 3000,
"density": 0.39493696217731078
},
{
"start": 3000,
"density": 0.073944366619972793
}
],
"percentiles": {
"p75": 1768
}
}
}
}
}
--batch_R4dQQd20Vo_-lf91w1QTFvMinqZc7Zyj--
编辑:我添加了一种方法来CrUXApiUtil
为您在 JS 应用程序中处理所有批处理物流。
CrUXApiUtil.batch = function (requests) {
if (CrUXApiUtil.API_KEY == '[YOUR_API_KEY]') {
throw 'Replace "YOUR_API_KEY" with your private CrUX API key. Get a key at https://goo.gle/crux-api-key.';
}
const BOUNDARY = 'BATCH_BOUNDARY';
return fetch(CrUXApiUtil.API_BATCH_ENDPOINT, {
method: 'POST',
headers: {
'Content-Type': `multipart/mixed; boundary="${BOUNDARY}"`
},
body: `--${BOUNDARY}\n` + requests.map((requestBody, i) => {
return `
POST ${CrUXApiUtil.API_ENDPOINT_PATH} HTTP/1.1
Content-ID: crux-${i}
Content-Type: application/json
${JSON.stringify(requestBody)}`;
}).join(`\n\n--${BOUNDARY}\n`) + `\n\n--${BOUNDARY}--`
}).then(response => {
const contentTypeHeader = response.headers.get('Content-Type');
const boundaryPattern = /\bboundary=([\w-]+)\b/i;
if (!boundaryPattern.test(contentTypeHeader)) {
throw `Unable to parse boundary directive from Content-Type response header: "${contentTypeHeader}"`;
}
const boundary = contentTypeHeader.match(boundaryPattern)[1];
return Promise.all([
Promise.resolve(boundary),
response.text()
]);
}).then(([boundary, response]) => {
const responseParts = response.split(`--${boundary}`);
// Eject boundary bookends
responseParts.shift();
responseParts.pop();
const responseJSONPattern = /\n({[\s\S]*)/m;
return responseParts.map(part => {
if (!responseJSONPattern.test(part)) {
console.error(`Unable to parse CrUX API response from:\n${response}`);
return null;
}
return JSON.parse(part.match(responseJSONPattern)[1]);
});
});
}
示例输入:
CrUXApiUtil.batch([
{"origin":"https://example.com", "metrics": ["first_contentful_paint"]},
{"url":"https://example.com/", "metrics": ["first_contentful_paint"]}
]).then(console.log)
示例输出:
[
{
"record": {
"key": {
"origin": "https://example.com"
},
"metrics": {
"first_contentful_paint": {
"histogram": [
{
"start": 0,
"end": 1000,
"density": 0.5374687343671887
},
{
"start": 1000,
"end": 3000,
"density": 0.39049524762381554
},
{
"start": 3000,
"density": 0.07203601800900532
}
],
"percentiles": {
"p75": 1748
}
}
}
}
},
{
"record": {
"key": {
"url": "https://example.com/"
},
"metrics": {
"first_contentful_paint": {
"histogram": [
{
"start": 0,
"end": 1000,
"density": 0.5311186712027276
},
{
"start": 1000,
"end": 3000,
"density": 0.3949369621773108
},
{
"start": 3000,
"density": 0.07394436661997279
}
],
"percentiles": {
"p75": 1768
}
}
}
}
}
]