使用JS消耗Rails send_data响应 [英] Using JS to consume a Rails send_data response

查看:79
本文介绍了使用JS消耗Rails send_data响应的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个连接到Rails API后端的VueJS前端.

I have a VueJS frontend that is connected to a Rails API backend.

在其中一个端点中,我正在使用 WickedPDF 来生成PDF.当我在浏览器中打开URL本身时,PDF可以很好地下载,并且可以完全按预期工作.当我通过Vue发送请求时,API会以一个看起来很奇怪的字符串响应,如下所示:

In one of the endpoints, I am using WickedPDF to generate a PDF. When I open the URL itself in a browser, the PDF downloads fine and works exactly as expected. When I send a request via Vue, the API responds with a weird looking string that looks like this:

%PDF-1.4
1 0 obj
<<
/Title (��)
/Creator (��wkhtmltopdf 0.12.4)
/Producer (��Qt 4.8.7)
/CreationDate (D:20190222102025+02'00')
>>
endobj
3 0 obj
<<
/Type /ExtGState
/SA true
/SM 0.02
/ca 1.0
/CA 1.0
/AIS false
...

我不太确定这是什么数据类型?我最初以为可能是BLOB,但我不知道.我遵循了此处概述的逻辑解析来自我的rails api的响应,该api确实将PDF下载到chrome.当打开此PDF时,它为空白,而chrome浏览器顶部的文件名是奇怪字符的组合.这使我认为我没有以正确的方式转换响应,并且最终出现了一些编码问题.

I am not really sure what data type this is? I initially thought that it might be a BLOB, but I have no idea. I followed the logic outlined here to parse the response from my rails api, which did download a PDF to chrome. When opening this PDF, it is blank and the file name at the top of the chrome browser is a combination of weird chars. This makes me think that I am not converting the response in the correct way and some encoding issue ends up happening.

这是我的Rails API代码:

Here is my Rails API code:

def pdf
  pdf_html = ActionController::Base.new.render_to_string(
    template: 'api/v1/exporters/pdf',
    layout: 'pdf',
    page_size: 'A4',
    formats: :html,
    encoding: 'utf8',
    margin: {
      top: 20,
      left: 20,
    }
  )
  pdf = WickedPdf.new.pdf_from_string(pdf_html)
  send_data(
    pdf,                                  
    filename: 'download.pdf',                     
    type: 'application/pdf',                      
    disposition: 'attachment'
  )
end

这是上面链接中的JS函数.我将Rails响应主体(在控制台登录时在第一个代码块中设置的是奇怪的字符集)作为唯一的参数传递:

Here is the JS function from the link above. I am passing the Rails response body (which when console logged is the weird looking char set in the first code block) as the only param:

showFile(blob){
  var newBlob = new Blob([blob], {type: "application/pdf"})

  if (window.navigator && window.navigator.msSaveOrOpenBlob) {
    window.navigator.msSaveOrOpenBlob(newBlob);
    return;
  } 

  const data = window.URL.createObjectURL(newBlob);
  var link = document.createElement('a');
  link.href = data;
  link.download="file.pdf";
  link.click();
  setTimeout(function(){
    window.URL.revokeObjectURL(data);
  , 100}
}

任何人都可以向我指出正确的方向,例如如何以正确的方式进行配置或如何以其他/更好的方式进行配置?甚至确认响应是哪种数据类型也可能对我有帮助.

Can anyone help point me in the right direction as to how to configure this in the right way or how to do it in a different/better way? Even a confirmation of what kind of data type the response is might help me.

推荐答案

如果您使用的是 axios 对于API调用,您可以指定客户端以blob格式下载数据.

If you are using axios for the API call, you can specify the client to download the data as blob.

import axios from 'axios';

axios
    .request({
       url: '/api-url-to-download-pdf',
       responseType: 'blob',
    })
    .then(response => response.data)
    .then(blob => {
        const data = URL.createObjectURL(blob );

        // ... do your stuff here ...
    .catch((err) => {
        // handle error
    });

如果您使用的是获取api API请求,

If you are using fetch api to make the API request,

fetch('/api-url-to-download-pdf', {
    headers: {
        Accept: 'application/pdf',
    },
    responseType: 'arraybuffer'
})
    .then(response => {
        console.log(response);
        if (response.ok) {
            return response.blob();
        }
    })
    .then(blob => {
        const data = URL.createObjectURL(blob);

        // ... do your stuff here ...
    })
    .catch((err) => {
        // handle error
    });

这篇关于使用JS消耗Rails send_data响应的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆