如何将 Request 对象转换为 JavaScript 中的可字符串化对象?

How can I convert a Request object into a stringifiable object in JavaScript?

使用 Object 方法,如 entrieskeys 生成空数组。 JSON.stringify 在浏览器中产生一个空对象,在 Node.js 中产生一个循环引用错误。

const request = new Request(
  'https://example.com/send',
  {
    method: 'POST',
    body: 'Hello world',
    headers: {'x-planet-origin': 'Mars'},
  },
);

const keys = Object.keys(request);
const values = Object.values(request);
const entries = Object.entries(request);
const string = JSON.stringify(request);

console.log({keys, values, entries, string, request});

您可以尝试这样的操作:

const request = new Request(
  'https://example.com/send',
  {
    method: 'POST',
    body: 'Hello world',
    headers: {'x-planet-origin': 'Mars'},
  },
);

const str = JSON.stringify(request, ['bodyUsed',
'cache',
'credentials',
'destination','headers',
'integrity',
'isHistoryNavigation',
'keepalive',
'method',
'mode',
'redirect',
'referrer',
'referrerPolicy',
'signal',
'url']);
 
console.log(str);

//iterating dinamically
let props = [];
for(let prop in request){
props.push(prop);
}

const str2 = JSON.stringify(request, props);
 
console.log(str2);

如您所见,signal 之类的属性会生成一个空对象,如果您不需要此类属性,这是一个可能的解决方案。

如果您仍然想要 signal 这样的属性,您可以在第二步中执行类似的操作:

const signal = JSON.stringify(request.signal, ['aborted', 'onabort']);

尝试const reqrCopy = JSON.parse(JSON.stringify(request))

然后您可以使用 keysentries 等(在副本上)执行您稍后尝试的所有方法。请求对象可能是嵌套的,因此您想这样做以对这些方法进行深度复制。

您可以使用这些函数将 Request 对象中的可字符串化值转换为普通对象中的值。第一个函数将单独生成所描述的对象,其他函数将协助生成具有排序属性的版本。

function requestAsObject (request) {
  if (!request instanceof Request)
    throw Object.assign(
      new Error(),
      {name: 'TypeError', message: 'Argument must be a Request object'}
    );
  request = request.clone();

  function stringifiableObject (obj) {
    const filtered = {};
    for (const key in obj)
      if (['boolean', 'number', 'string'].includes(typeof obj[key]) || obj[key] === null)
        filtered[key] = obj[key];
    return filtered;
  }

  return {
    ...stringifiableObject(request),
    headers: Object.fromEntries(request.headers),
    signal: stringifiableObject(request.signal),
    // bodyText: await request.text(), // requires function to be async
  };
}

function requestAsArrayEntries (request) {
  if (!request instanceof Request)
    throw Object.assign(
      new Error(),
      {name: 'TypeError', message: 'Argument must be a Request object'}
    );
  request = request.clone();

  function entriesFromObject (obj) {
    const entries = [];
    for (const key in obj)
      if (['boolean', 'number', 'string'].includes(typeof obj[key]) || obj[key] === null)
        entries.push([key, obj[key]]);
    return entries.sort();
  }

  return [
    ...entriesFromObject(request),
    ['headers', [...request.headers].sort()],
    ['signal', entriesFromObject(request.signal)],
    // ['bodyText', await request.text()], // requires function to be async
  ].sort();
}

function objectFromNestedEntries (arrayOfEntries) {
  if (!Array.isArray(arrayOfEntries)) return arrayOfEntries;
  const obj = {};
  for (const [key, value] of arrayOfEntries) {
    obj[key] = objectFromNestedEntries(value);
  }
  return obj;
}

const request = new Request('https://example.com/send', {
  method: 'POST',
  body: 'Hello world',
  headers: {'x-planet-origin': 'Mars'},
});

const object = requestAsObject(request);
const arrayEntries = requestAsArrayEntries(request);
const sortedObject = objectFromNestedEntries(arrayEntries);

console.log({
  object,
  arrayEntries,
  sortedObject,
  objectAsString: JSON.stringify(object),
  sortedObjectAsString: JSON.stringify(sortedObject),
});

谢谢,Emeeus, for