【问题标题】:Img src="blob:http://localhost... doesn't work - neither with createObjectURL or readAsDataURL | Firebase | Vue.jsImg src="blob:http://localhost... 不起作用 - createObjectURL 或 readAsDataURL | Firebase | Vue.js
【发布时间】:2021-01-19 19:04:11
【问题描述】:

我想我现在已经尝试了所有方法并阅读了有关此问题的所有问题,但我仍然无法正常工作..

Cart.vue

<template>
<div>
<h1>CART</h1>
  <img :src="imgSrc" style="width:600px; height: 600px">
</div>
</template>

Cart.vue mount()

mounted(){
    const qr = firebase.functions().httpsCallable('sendPaymentRequest')
    qr()
      .then(res => {
        const blob = new Blob([res.data], {type: 'image/jpg'})
        console.log(blob);
        const url = (window.URL || window.webkitURL).createObjectURL(blob)
        console.log(url);
        this.imgSrc = url;
      })

Firebase 函数

exports.sendPaymentRequest = functions.https.onCall((data, context) => {
const qr = async () => {
       try {
        const json = {
            token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
            size: "300",
            format: "jpg",
            border: "0"
        }
        const response = await axios.post('https://mpc.getswish.net/qrg-swish/api/v1/commerce', json)
       console.log('status', response.status)
       if(response.status !== 200){throw new Error ('Error requesting QR code')}
        return response.data
    } catch (e){
        console.log('error', e)
        return e
    }
    }
    return qr();
})

在我的 2 个控制台日志中,mounted() 挂钩 - Blob 和 URL - 我得到:

看起来还不错吧?好像有Blob?还有网址?

然而:

...所以我尝试将 mounted() 更改为

const qr = firebase.functions().httpsCallable('sendPaymentRequest')
qr()
.then(res => {
  const self = this;
  const blob = new Blob([res.data], {type: 'image/jpg'})
  const reader = new FileReader();
  reader.onloadend = function() {
    self.imgSrc = reader.result
  };
  reader.readAsDataURL(blob);
})
.catch(e => console.log(e))

这似乎也有效,但是..它不是..现在我的图像得到了一个不错的 base64 编码的小字符串,而不是 URL:

但仍然没有图像..

所以我尝试了在阅读所有 Internet 时发现的其他一些东西。从可调用函数转移到 onRequest 函数等。当我与 Postman 执行完全相同的请求时,我在回复..

如果我在 firebase 函数中登录 response.headers,我会看到

'内容类型':'图像/jpeg', “内容长度”:“31476”,

所以在服务器上我得到了一张图片..我用return response.data发送它

response.data 是:

����JFIF��C

$.' ",#(7),01444'9=82<.342>

2!!22222222222222222222222222222222222222222222222222�,,"��

等等..

这就是我所处的位置……我越来越……沮丧。

这里有人看到我做错了吗??

编辑 1 对于将来遇到此问题的任何人-正如@Kaiido 在客户端上指出的那样,我必须添加

  ...
  responseType: "blob"
}

也在服务器上,您需要从 Firebase 移出

functions.https.onCall(async (data, context) => {

functions.https.onRequest(async (req, res) => {

在客户端调用它:

axios({
        method: 'get',
        url: 'http://localhost:5001/swook-4f328/us-central1/retrieveQr',
        responseType: 'blob',
       })
        .then(async res => {
          const url = (window.URL || window.webkitURL).createObjectURL(res.data)
          this.imgSrc = url;
          
        })
        .catch(e => e)

在服务器上 而不是 axios 使用请求(出于某种原因,但这有效.. 不知道为什么,但现在解决了问题,尽管我很好奇为什么并且我更喜欢 axios 来请求)

有效

const json = {
        token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
        size: "300",
        format: "png",
        border: "0"
    }
var requestSettings = {
    url: 'https://mpc.getswish.net/qrg-swish/api/v1/commerce',
    method: 'POST',
    encoding: null,
    json: true,
    'content-type': 'application/json',
    body: json,
};

request(requestSettings, (error, response, body) => {
    res.set('Content-Type', 'image/png');
    res.header({"Access-Control-Allow-Origin": "*"});
    res.send(body);
});

不起作用

const json = {
    token: "umP7Eg2HT_OUId8Mc0FHPCxhX3Hkh4qI",
    size: "300",
    format: "png",
    border: "0"
}
const response =  await axios.post('https://mpc.getswish.net/qrg-swish/api/v1/commerce', json)
if(response.status !== 200){throw new Error ('Error requesting QR code')}
res.header({"Access-Control-Allow-Origin": "*"}).writeHead(200, {'Content-Type': 'image/png'}).end(response.data)
// neither this works:
// res.header({"Access-Control-Allow-Origin": "*"}).status(200).send(response.data)

【问题讨论】:

    标签: javascript node.js firebase vue.js google-cloud-functions


    【解决方案1】:

    您正在接收一个 utf8 编码的文本,二进制响应中的一些字节已被损坏。

    在做你的请求时,添加一个额外的

      ...
      responseType: "blob"
    }
    

    您的 axios 请求的选项,这将确保二进制数据不会被读取为文本,而是正确保存。
    另外,现在您不需要自己构建 Blob,它已经是 response.data 中的一个。

    【讨论】:

    • 谢谢!我更近了一步,但还没有。通过这样做,我现在在我的“数据”中收到一个 Blob,但 Blob 的内容类型是“text/html”,尽管我来自我的服务器发送API调用的直接响应,即“图像/ jpeg”。我已从httpsCallable转移到“常规” https函数,我使用客户端的axios请求该函数。 Bc CORS 我不能直接从客户端调用第 3 方 API,但基本上服务器只是进行调用,返回响应,但不知何故,它在传输时转换为 text/html.. 现在太近了!!非常感谢!
    • @JohnAlfredsson 如果你这样做console.log( await blobtext() ) 你仍然得到正确的����JFIF��C 内容吗?如果是这样,您应该修复服务器端以发送正确的 heders,但您始终可以通过执行 new Blob([blob], { type: "image/jpeg" }); 来强制 mime 类型
    • 正确,blob.text() 让我得到那个内容.. 我刚刚想通了,虽然在服务器上我应该做res.header({"Access-Control-Allow-Origin": "*"}).writeHead(200, {'Content-Type': 'image/jpeg'}).end(response.data)而不是res.status(200).send(response.data) - 这给了我 Blob 作为图像/jpeg 在客户端.. 但它仍然不呈现.. 我是否需要使用 fs 或其他东西将服务器上的 response.data 作为文件读取?或者 writeStream.. 非常感谢您的帮助,我是这方面的初学者,意义重大!
    • 好的!我让它工作。 responseType: "blob" 必须在客户端上设置.. 但是第二部分不起作用的是我的服务器上似乎我对 axios 做错了,因为我让它可以处理请求.. 为什么我是现在不确定,阅读它..在服务器上使用 axios 时注意到客户端的 blob 大小为 96292,而请求为 53453..我的 axios 调用/响应一定有问题..
    • 编辑了我的原始问题以包含代码示例.. 将在您回答时将此标记为已回答,axios/request 似乎是一个单独的问题!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2014-03-17
    • 1970-01-01
    • 2021-09-29
    • 1970-01-01
    • 2023-04-03
    • 2017-03-19
    • 1970-01-01
    • 2012-07-14
    相关资源
    最近更新 更多