diff --git a/src/components/gltf-model-plus.js b/src/components/gltf-model-plus.js
index 33699eacf7d127c506ae99740a137a2853890efa..4ca78bb33c89f0b62f36307ff1e7d9807560ecb2 100644
--- a/src/components/gltf-model-plus.js
+++ b/src/components/gltf-model-plus.js
@@ -215,7 +215,7 @@ async function resolveGLTFUri(gltfProperty, basePath) {
   if (url.protocol === "blob:") {
     gltfProperty.uri = url.href;
   } else {
-    const { raw } = await resolveMedia(url.href);
+    const { raw } = await resolveMedia(url.href, null, true);
     gltfProperty.uri = raw;
   }
 }
diff --git a/src/components/media-loader.js b/src/components/media-loader.js
index 0cc6792ab211b2d6d8059368134aa24eeeffe1f4..81303a07d67946e187ea7664252dab3af20846b3 100644
--- a/src/components/media-loader.js
+++ b/src/components/media-loader.js
@@ -13,6 +13,13 @@ AFRAME.registerComponent("media-loader", {
     this.showLoader = this.showLoader.bind(this);
   },
 
+  remove() {
+    if (this.blobURL) {
+      URL.revokeObjectURL(this.blobURL);
+      this.blobURL = null;
+    }
+  },
+
   setShapeAndScale(resize) {
     const mesh = this.el.getObject3D("mesh");
     const box = getBox(this.el, mesh);
@@ -58,16 +65,19 @@ AFRAME.registerComponent("media-loader", {
 
       if (!url) return;
 
-      const { raw, contentType } = await resolveMedia(url, token);
+      const { raw, origin, contentType } = await resolveMedia(url, token);
 
-      let blobUrl;
       if (token) {
+        if (this.blobURL) {
+          URL.revokeObjectURL(this.blobURL);
+          this.blobURL = null;
+        }
         const response = await fetch(raw, {
           method: "GET",
           headers: { Authorization: `Token ${token}` }
         });
         const blob = await response.blob();
-        blobUrl = window.URL.createObjectURL(blob);
+        this.blobURL = window.URL.createObjectURL(blob);
       }
 
       if (contentType.startsWith("image/") || contentType.startsWith("video/") || contentType.startsWith("audio/")) {
@@ -78,7 +88,7 @@ AFRAME.registerComponent("media-loader", {
           },
           { once: true }
         );
-        this.el.setAttribute("image-plus", { src: blobUrl || raw, contentType, token });
+        this.el.setAttribute("image-plus", { src: this.blobURL || raw, contentType, token });
         this.el.setAttribute("position-at-box-shape-border", { target: ".delete-button", dirs: ["forward", "back"] });
       } else if (
         contentType.includes("application/octet-stream") ||
@@ -96,8 +106,9 @@ AFRAME.registerComponent("media-loader", {
           { once: true }
         );
         this.el.addEventListener("model-error", this.onError, { once: true });
+        const src = this.blobURL || origin || url;
         this.el.setAttribute("gltf-model-plus", {
-          src: blobUrl || url,
+          src,
           contentType,
           inflate: true
         });
diff --git a/src/utils/media-utils.js b/src/utils/media-utils.js
index 36debd69e3a1dceecf01fd1cc6842ea0e11237d3..dc7d5773085acee914e3b70d894d0b14adfe221b 100644
--- a/src/utils/media-utils.js
+++ b/src/utils/media-utils.js
@@ -17,7 +17,7 @@ const fetchContentType = async (url, token) => {
 };
 
 const resolveMediaCache = new Map();
-export const resolveMedia = async (url, token) => {
+export const resolveMedia = async (url, token, skipContentType) => {
   const parsedUrl = new URL(url);
   if (resolveMediaCache.has(url)) return resolveMediaCache.get(url);
 
@@ -31,7 +31,7 @@ export const resolveMedia = async (url, token) => {
           body: JSON.stringify({ media: { url } })
         }).then(r => r.json());
 
-  if (!isNotHttpOrHttps) {
+  if (!isNotHttpOrHttps && !skipContentType) {
     const contentType =
       (resolved.meta && resolved.meta.expected_content_type) || (await fetchContentType(resolved.raw, token));
     resolved.contentType = contentType;