您正在寻找Content-Disposition 标头。将其包含在您的回复中,如下所示:
Content-Disposition: attachment; filename=error.csv
Web 浏览器会将响应正文视为要下载的文件(在本例中为“error.csv”)。
但是,修改代码以执行此操作会因两件事而变得复杂:
尝试将此添加到您的 API 类中:
# Handle all exceptions with an error response appropriate to the requested
# output format
rescue_from :all do |e|
# Edit this hash to override the HTTP response status for specific output
# formats
FORMAT_SPECIFIC_STATUS = {
:csv => 200
}
# Edit this hash to add custom headers specific to each output format
FORMAT_SPECIFIC_HEADERS = {
:csv => {
'Content-Disposition' => 'attachment; filename=error.csv'
}
}
# Get the output format requested by the user
format = env['api.format']
# Set the HTTP status appropriately for the requested output format and
# the error type
status = FORMAT_SPECIFIC_STATUS[format] ||
(e.respond_to? :status) && e.status ||
500
# Set the HTTP headers appropriately for the requested format
headers = {
'Content-Type' => options[:content_types][format] || 'text/plain'
}.merge(FORMAT_SPECIFIC_HEADERS[format] || { })
# Format the message body using the appropriate error formatter
error_formatter =
options[:error_formatters][format] || options[:default_error_formatter]
body = error_formatter.call(e.message, nil, options, env)
# Return the error response to the client in the correct format
# with the correct HTTP headers for that format
Rack::Response.new(body, status, headers).finish
end
现在,如果您将 API 类配置为处理两种不同的格式(为简单起见,我在这里选择了 CSV 和纯文本),如下所示:
module Errors
module CSVErrorFormatter
def self.call(message, backtrace, options, env)
as_csv = "CSV formatter:" + "\n"
message.split(",").each do |msg|
as_csv += msg + "\n"
end
# Note this method simply returns the response body
as_csv
end
end
module TextErrorFormatter
def self.call(message, backtrace, options, env)
as_txt = "Text formatter:" + "\n"
message.split(",").each do |msg|
as_txt += msg + "\n"
end
as_txt
end
end
end
content_type :csv, 'text/csv'
content_type :txt, 'text/plain'
error_formatter :csv, Api::Base::Errors::CSVErrorFormatter
error_formatter :txt, Api::Base::Errors::TextErrorFormatter
您应该会发现您的 API 始终返回适合请求格式的错误响应,并且仅在请求 CSV 格式时触发浏览器下载响应。当然,这可以通过显式声明内容类型和错误格式化程序来扩展以支持尽可能多的格式。
请注意,在这种情况下,此代码不会自动执行正确的操作,那就是直接使用error!
. 在这种情况下,您必须提供正确的正文和标头作为调用本身的一部分。我将把上述代码的相关部分提取到可重用的方法中,作为读者的练习。