使用 send_file 下载 txt 文件时,safari 和 chrome 浏览器无法解析它

Posted

技术标签:

【中文标题】使用 send_file 下载 txt 文件时,safari 和 chrome 浏览器无法解析它【英文标题】:When downloading a txt-file with send_file, safari and chrome browsers are not able to parse it 【发布时间】:2021-10-18 11:41:51 【问题描述】:

我有一组entries,每个描述包含几个句子。我需要将所有这些句子导出到一个 `txt 文件中。每个句子都有一个唯一的 id 并从新行开始。

0000000001[tab] This is line one
0000000002[tab] This is line two

我在Entry model中创建了一个class method,用于根据上述内容创建一个文本文件。正在存储此文件,我可以打开它。

我还创建了一个controller-action 用于下载文件。此操作首先创建一个带有blocktemporary directory,其中正在调用class method(伴随着directory),然后将文件发送到浏览器。

日志显示文件已成功交付,但ChromeSafari 给出了parsing error

entry_model.rb

  def self.download_strings_as_script(dir)
    # Preparing an empty array
    a = []
    # Seeding the array with sentences from all entries which have original content
    Entry.with_original_content.each do |e|
      m = e.original_content.scan(/[^.?!]*[^.?!]*[.?!]/)
      m.each do |me|
        a << me
      end
    end
    # Filtering out some known unnesecary characters and patterns
    a = a.map |am| am.gsub(/(---)/, "")
    a = a.map |am| am.gsub(/^\s+/, "")
    # Creating the textfile with the array
    File.open("#dir/custom_voice_script.txt", 'w+') do |f|
      a.each_with_index do |ae,id|
          # giving the proper format per string, including an id to be used during recording
          f.puts ("%010d" % id) + "[tab] " + ae
      end
    end

entry_controller.rb

  def download_script
    #Create a temporary directory for writing the textfile to
    Dir.mktmpdir do |dir|
      Entry.download_strings_as_script(dir)
      # Waiting 10 seconds
      sleep(10.seconds)
      # Downloading the textfile
      send_file(
        "#dir/custom_voice_script.txt",
        filename: "custom_voice_script.txt",
        type: "text/plain"
      )
    end
  end

routes.rb

get 'download_script' => 'entries#download_script'

查看

<%= link_to 'Download Voice Script', admin_download_script_path, :format => 'text/plain' %>

我可能只是愚蠢,但谁能看出我哪里出错了?

更新

以下是浏览器错误: Chrome 正在给我一个Failed - Network error。还有inspect:

turbolinks.js:154 GET http://127.0.0.1:3000/nl/admin/download_script net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 (OK)
r.send  @   turbolinks.js:154
r.issueRequest  @   turbolinks.js:790
r.visitStarted  @   turbolinks.js:273
r.start @   turbolinks.js:776
r.startVisit    @   turbolinks.js:1002
r.startVisitToLocationWithAction    @   turbolinks.js:894
r.visitProposedToLocationWithAction @   turbolinks.js:271
r.visit @   turbolinks.js:891
r.clickBubbled  @   turbolinks.js:953
(anonymous) @   turbolinks.js:872

Safari 只给我:cannot parse response" (NSURLErrorDomain:-1017)

【问题讨论】:

确切的错误是什么?是后端错误还是浏览器给你一个特定的错误? @DennyMueller 我已将浏览器错误添加为问题的更新。我在后端得到了 Completed 200 OK。 【参考方案1】:

该错误已经为您提供了正确的提示。 Turbolinks 无法处理使用sent_filesend_data 的此类链接。您必须使用 data-no-turbolink 选项来禁用 turbolink。

<%= link_to 
  'Download Voice Script', 
  admin_download_script_path, 
  format: 'text/plain',
  data:  turbolinks: false 
%>

如果您使用低于 5 的 rails 版本,则该选项应为 data: no_turbolink: true

【讨论】:

感谢您的努力,丹尼。但似乎 turbolink 错误只是一个症状。 Dir.mktmpdir block 导致了问题。如果我不通过关闭块立即删除临时目录,一切正常。

以上是关于使用 send_file 下载 txt 文件时,safari 和 chrome 浏览器无法解析它的主要内容,如果未能解决你的问题,请参考以下文章

Python Flask send_file StringIO 空白文件

来自 Flask send_file 的 Zip 文件无效

send_file()后烧瓶无法删除文件[重复]

使用烧瓶中的 send_file() 时文件损坏,pymongo gridfs 中的数据

Flask send_file 返回 200 OK 但不发送文件

使用Python Flask中的send_file发送视频时移动设备发生错误http://mattspitz.me/2013/11/20/serving-authenticated-media-wit