{"id":17458,"date":"2025-09-15T11:45:03","date_gmt":"2025-09-15T11:45:03","guid":{"rendered":"http:\/\/localhost\/?p=17458"},"modified":"2025-09-15T11:45:03","modified_gmt":"2025-09-15T11:45:03","slug":"fetch-streams-are-great-but-not-for-measuring-uploaddownloading-progress","status":"publish","type":"post","link":"https:\/\/zero.redgem.net\/?p=17458","title":{"rendered":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12"},"content":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-09-15T16:34:27&#8243;,&#8221;description&#8221;:&#8221;Part of my role at Mozilla is making sure we&#8217;re focusing on the right features, and we got onto the topic of fetch upload streams. It&#8217;s something Chrome has supported for a while, but it isn&#8217;t yet supported in either Firefox or Safari.\\n\\nI asked folks on various social platforms what they thought of the feature, and what they&#8217;d use it for. The most common answer by far was \\&#8221;to measure upload progress\\&#8221;, but\u2026 using it for that will give inaccurate results, and may even lead to bad implementations in browsers.\\n\\nLet&#8217;s dig in\u2026\\n\\n## Response streams\\n\\nStreaming responses have been available in all browsers for years now:\\n    \\n    \\n    const response = await fetch(url);\\n    const reader = response.body.getReader();\\n    \\n    while (true) {\\n      const { done, value } = await reader.read();\\n      if (done) break;\\n      console.log(value);\\n    }\\n    \\n    console.log(&#8216;Done!&#8217;);\\n\\nThis lets you get the response chunk-by-chunk, so you can start processing it as you receive it.\\n\\nThis is even easier with async iterators:\\n    \\n    \\n    const response = await fetch(url);\\n    \\n    for await (const chunk of response.body) {\\n      console.log(chunk);\\n    }\\n    \\n    console.log(&#8216;Done!&#8217;);\\n\\n\u2026but that isn&#8217;t supported in Safari. I&#8217;ve proposed it for interop 2026.\\n\\nThe chunks are `Uint8Array`s, but you can use `TextDecoder` to get the chunks as text.\\n\\n### But they&#8217;re not ideal for measuring download progress\\n\\nYou could try to measure download progress like this:\\n    \\n    \\n    \/\/ THIS DOESN&#8217;T ALWAYS WORK!\\n    const response = await fetch(url);\\n    const contentLength = Number(response.headers.get(&#8216;Content-Length&#8217;)) || 0;\\n    let downloaded = 0;\\n    \\n    for await (const chunk of response.body) {\\n      downloaded += chunk.length;\\n      if (contentLength) {\\n        console.log(\\n          `Downloaded ${((contentLength \/ downloaded) * 100).toFixed(2)}%`,\\n        );\\n      }\\n    }\\n\\nThe good part is that you&#8217;re measuring the point at which you have the data, which is what matters when it comes to download. Let&#8217;s say you were receiving three packages via mail \u2013 you&#8217;re measuring the point each package arrives in your possession, which is fine.\\n\\nHowever, this all falls down if the response has a `Content-Encoding`, because in that case the `Content-Length` represents the encoded size, but the chunks are _decoded_ chunks. This means your `downloaded` value is likely to exceed the `contentLength` value.\\n\\nThere&#8217;s a feature request for a way to get the raw body, without decompressing.\\n\\n## Request streams\\n\\nRequest streams are basically the same as response streams, but for uploads rather than downloads. Imagine a video uploading app that did some transcoding\/processing of the video before uploading:\\n    \\n    \\n    \/\/ Get a video from disk, or from the camera\\n    const videoStream = getVideoStreamSomehow();\\n    \/\/ Process it in some way, e.g. editing or transcoding\\n    const processedVideo = videoStream.pipeThrough(new SomeVideoProcessor());\\n    \\n    \/\/ Upload the stream\\n    await fetch(url, {\\n      method: &#8216;POST&#8217;,\\n      body: processedVideo,\\n      duplex: &#8216;half&#8217;,\\n      headers: {\\n        &#8216;Content-Type&#8217;: &#8216;video\/mp4&#8217;,\\n      },\\n    });\\n\\nIn this model, the video processing can happen in parallel with the uploading. More traditional methods would require processing the whole video before the upload begins, which is potentially much slower.\\n\\n### Restrictions\\n\\n`duplex: &#8216;half&#8217;` means that the request must complete before the response becomes available. This &#8216;reserves&#8217; a future feature where browsers can support handling the request and response in parallel.\\n\\nIf you want to have a request and response in parallel, you can perform two fetches \u2013 one that streams request data, and another that streams response data.\\n\\nAlso, since the `Content-Length` of the request isn&#8217;t known, the feature is restricted to transports that are already used to handling request data in chunks, which is HTTP\/2 onwards.\\n\\n### But they&#8217;re bad for measuring upload progress\\n\\nI&#8217;m not even going to show the code for this because it&#8217;s too unreliable.\\n\\nWith _request_ streams, you end up measuring the point at which the data is taken from your stream. In terms of the postal metaphor, you&#8217;re measuring the point each package is collected by the courier, which does not represent the delivery of those packages.\\n\\nFetch is the courier. It will take some chunks off your hands and start handling the network parts. Successfully sending those chunks will happen later, or maybe it will fail.\\n\\nThis is normal behaviour with streams, and it helps keep everything running as smoothly as possible in cases where parts of the pipe flow quicker than others. Each stream has a \\&#8221;high water mark\\&#8221;, which is essentially an ideal amount to buffer.\\n\\n### Using streams to measure upload progress could cause problems in future\\n\\nIf you try to use streams to measure upload progress, the results will be inaccurate, but it may also limit the quality of this feature in future.\\n\\nLet&#8217;s say browsers ship this, and do a fairly small amount of buffering. If folks use this for upload progress, it won&#8217;t be right, but it might be close enough.\\n\\nThen let&#8217;s say a browser discovers that they can get better performance by buffering more within fetch. If large parts of the web are using this feature for upload progress, that browser faces two choices: Ship the change, which means these websites&#8217; upload progress measurements become even less accurate, or avoid shipping the general improvement. I don&#8217;t want browsers to end up having to make a compromise here.\\n\\n## How to measure upload progress\\n\\nUpload and download progress is unfortunately a missing feature in fetch. If you want progress events _today_ , the best way is to use XHR:\\n    \\n    \\n    const xhr = new XMLHttpRequest();\\n    \\n    \/\/ Upload progress\\n    xhr.upload.onprogress = (event) =\\u003e {\\n      if (event.lengthComputable) {\\n        console.log(\\n          `Uploaded ${((event.loaded \/ event.total) * 100).toFixed(2)}%`,\\n        );\\n      }\\n    };\\n    \\n    \/\/ Download progress\\n    xhr.onprogress = (event) =\\u003e {\\n      if (event.lengthComputable) {\\n        console.log(\\n          `Downloaded ${((event.loaded \/ event.total) * 100).toFixed(2)}%`,\\n        );\\n      }\\n    };\\n    \\n    xhr.open(&#8216;POST&#8217;, url);\\n    xhr.send(blobOrWhatever);\\n\\n## But in future\u2026\\n\\nLuke Warlow from Igalia is currently working on an API for fetch to add progress events for both uploads and downloads.\\n\\nThe API might change before it lands, but right now it looks like this:\\n    \\n    \\n    const response = await fetch(url, {\\n      observer(requestObserver, responseObserver) {\\n        requestObserver.onprogress = (event) =\\u003e {\\n          if (event.lengthComputable) {\\n            console.log(\\n              `Uploaded ${((event.total \/ event.loaded) * 100).toFixed(2)}%`,\\n            );\\n          }\\n        };\\n    \\n        responseObserver.onprogress = (event) =\\u003e {\\n          if (event.lengthComputable) {\\n            console.log(\\n              `Downloaded ${((event.total \/ event.loaded) * 100).toFixed(2)}%`,\\n            );\\n          }\\n        };\\n      },\\n    });\\n\\nThis should give us all the modern benefits of `fetch`, while plugging the progress feature gap!\\n\\nIf you&#8217;re interested in using request streams for things other than progress events, there&#8217;s an Interop 2026 proposal for them. We also want to gauge developer interest via this survey, or via the interop GitHub thread.&#8221;,&#8221;published&#8221;:&#8221;2025-09-15T01:00:00&#8243;,&#8221;modified&#8221;:&#8221;2025-09-15T01:00:00&#8243;,&#8221;type&#8221;:&#8221;jakearchibald&#8221;,&#8221;title&#8221;:&#8221;Fetch streams are great, but not for measuring upload\/downloading progress&#8221;,&#8221;source&#8221;:&#8221;&#8221;,&#8221;references&#8221;:&#8221;&#8221;,&#8221;id&#8221;:&#8221;JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12&#8243;,&#8221;bulletinFamily&#8221;:&#8221;blog&#8221;,&#8221;cwe&#8221;:null,&#8221;cvelist&#8221;:[],&#8221;sourceData&#8221;:&#8221;&#8221;,&#8221;sourceHref&#8221;:&#8221;&#8221;,&#8221;cvss&#8221;:{&#8220;score&#8221;:0,&#8221;severity&#8221;:&#8221;NONE&#8221;,&#8221;vector&#8221;:&#8221;NONE&#8221;,&#8221;version&#8221;:&#8221;NONE&#8221;},&#8221;cvss2&#8243;:{},&#8221;cvss3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;,&#8221;cvssV3&#8243;:{&#8220;version&#8221;:&#8221;&#8221;,&#8221;vectorString&#8221;:&#8221;&#8221;,&#8221;baseScore&#8221;:0,&#8221;baseSeverity&#8221;:&#8221;&#8221;,&#8221;attackVector&#8221;:&#8221;&#8221;,&#8221;attackComplexity&#8221;:&#8221;&#8221;,&#8221;privilegesRequired&#8221;:&#8221;&#8221;,&#8221;userInteraction&#8221;:&#8221;&#8221;,&#8221;scope&#8221;:&#8221;&#8221;,&#8221;confidentialityImpact&#8221;:&#8221;&#8221;,&#8221;integrityImpact&#8221;:&#8221;&#8221;,&#8221;availabilityImpact&#8221;:&#8221;&#8221;}},&#8221;href&#8221;:&#8221;https:\/\/jakearchibald.com\/2025\/fetch-streams-not-for-progress\/&#8221;,&#8221;category_name&#8221;:&#8221;News&#8221;,&#8221;post_link&#8221;:&#8221;&#8221;,&#8221;product&#8221;:&#8221;&#8221;,&#8221;version&#8221;:&#8221;&#8221;,&#8221;vendor&#8221;:&#8221;&#8221;,&#8221;ai_description&#8221;:&#8221;&#8221;,&#8221;ai_severity&#8221;:&#8221;&#8221;,&#8221;ai_vendor&#8221;:&#8221;&#8221;,&#8221;ai_product&#8221;:&#8221;&#8221;,&#8221;ai_version&#8221;:&#8221;&#8221;,&#8221;ai_score&#8221;:0}<\/p>\n","protected":false},"excerpt":{"rendered":"<p>{&#8220;lastseen&#8221;:&#8221;2025-09-15T16:34:27&#8243;,&#8221;description&#8221;:&#8221;Part of my role at Mozilla is making sure we&#8217;re focusing on the right features, and we got onto the topic of fetch upload streams&#8230;.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[4],"tags":[6,8,12,161,13,33,7,11,5],"class_list":["post-17458","post","type-post","status-publish","format-standard","hentry","category-category_news","tag-cve","tag-cvss","tag-exploit","tag-jakearchibald","tag-news","tag-none","tag-security","tag-tapic","tag-vulnerability"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.5 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/zero.redgem.net\/?p=17458\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem\" \/>\n<meta property=\"og:description\" content=\"{&#8220;lastseen&#8221;:&#8221;2025-09-15T16:34:27&#8243;,&#8221;description&#8221;:&#8221;Part of my role at Mozilla is making sure we&#8217;re focusing on the right features, and we got onto the topic of fetch upload streams....\" \/>\n<meta property=\"og:url\" content=\"https:\/\/zero.redgem.net\/?p=17458\" \/>\n<meta property=\"og:site_name\" content=\"zero redgem\" \/>\n<meta property=\"article:published_time\" content=\"2025-09-15T11:45:03+00:00\" \/>\n<meta name=\"author\" content=\"invoker\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"invoker\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458\"},\"author\":{\"name\":\"invoker\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\"},\"headline\":\"Fetch streams are great, but not for measuring upload\\\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12\",\"datePublished\":\"2025-09-15T11:45:03+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458\"},\"wordCount\":1321,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"keywords\":[\"CVE\",\"CVSS\",\"exploit\",\"jakearchibald\",\"news\",\"NONE\",\"Security\",\"tapic\",\"Vulnerability\"],\"articleSection\":[\"category_news\"],\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=17458#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458\",\"name\":\"Fetch streams are great, but not for measuring upload\\\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\"},\"datePublished\":\"2025-09-15T11:45:03+00:00\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/zero.redgem.net\\\/?p=17458\"]}]},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/?p=17458#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/zero.redgem.net\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Fetch streams are great, but not for measuring upload\\\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#website\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"name\":\"zero redgem\",\"description\":\"\",\"publisher\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/zero.redgem.net\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#organization\",\"name\":\"zero redgem\",\"url\":\"https:\\\/\\\/zero.redgem.net\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"\",\"contentUrl\":\"\",\"width\":191,\"height\":188,\"caption\":\"zero redgem\"},\"image\":{\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/logo\\\/image\\\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/zero.redgem.net\\\/#\\\/schema\\\/person\\\/fbfeae8dfad117ac08a7621bee1a1dca\",\"name\":\"invoker\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g\",\"caption\":\"invoker\"},\"sameAs\":[\"https:\\\/\\\/zero.redgem.net\"],\"url\":\"https:\\\/\\\/zero.redgem.net\\\/?author=1\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/zero.redgem.net\/?p=17458","og_locale":"en_US","og_type":"article","og_title":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem","og_description":"{&#8220;lastseen&#8221;:&#8221;2025-09-15T16:34:27&#8243;,&#8221;description&#8221;:&#8221;Part of my role at Mozilla is making sure we&#8217;re focusing on the right features, and we got onto the topic of fetch upload streams....","og_url":"https:\/\/zero.redgem.net\/?p=17458","og_site_name":"zero redgem","article_published_time":"2025-09-15T11:45:03+00:00","author":"invoker","twitter_card":"summary_large_image","twitter_misc":{"Written by":"invoker","Est. reading time":"6 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/zero.redgem.net\/?p=17458#article","isPartOf":{"@id":"https:\/\/zero.redgem.net\/?p=17458"},"author":{"name":"invoker","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca"},"headline":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12","datePublished":"2025-09-15T11:45:03+00:00","mainEntityOfPage":{"@id":"https:\/\/zero.redgem.net\/?p=17458"},"wordCount":1321,"commentCount":0,"publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"keywords":["CVE","CVSS","exploit","jakearchibald","news","NONE","Security","tapic","Vulnerability"],"articleSection":["category_news"],"inLanguage":"en-US","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/zero.redgem.net\/?p=17458#respond"]}]},{"@type":"WebPage","@id":"https:\/\/zero.redgem.net\/?p=17458","url":"https:\/\/zero.redgem.net\/?p=17458","name":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12 - zero redgem","isPartOf":{"@id":"https:\/\/zero.redgem.net\/#website"},"datePublished":"2025-09-15T11:45:03+00:00","breadcrumb":{"@id":"https:\/\/zero.redgem.net\/?p=17458#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/zero.redgem.net\/?p=17458"]}]},{"@type":"BreadcrumbList","@id":"https:\/\/zero.redgem.net\/?p=17458#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/zero.redgem.net\/"},{"@type":"ListItem","position":2,"name":"Fetch streams are great, but not for measuring upload\/downloading progress_JAKEARCHIBALD:86F958B36A61EDE7753356DC1A0F7F12"}]},{"@type":"WebSite","@id":"https:\/\/zero.redgem.net\/#website","url":"https:\/\/zero.redgem.net\/","name":"zero redgem","description":"","publisher":{"@id":"https:\/\/zero.redgem.net\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/zero.redgem.net\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Organization","@id":"https:\/\/zero.redgem.net\/#organization","name":"zero redgem","url":"https:\/\/zero.redgem.net\/","logo":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/","url":"","contentUrl":"","width":191,"height":188,"caption":"zero redgem"},"image":{"@id":"https:\/\/zero.redgem.net\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/zero.redgem.net\/#\/schema\/person\/fbfeae8dfad117ac08a7621bee1a1dca","name":"invoker","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/f17c01d7338e6932bcde121cf83569393df3374625d25afd62677cfb528f2e3e?s=96&d=mm&r=g","caption":"invoker"},"sameAs":["https:\/\/zero.redgem.net"],"url":"https:\/\/zero.redgem.net\/?author=1"}]}},"_links":{"self":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/17458","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=17458"}],"version-history":[{"count":0,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=\/wp\/v2\/posts\/17458\/revisions"}],"wp:attachment":[{"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=17458"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=17458"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zero.redgem.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=17458"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}