Download file, filename

我的梦境 提交于 2019-12-24 05:33:25

问题


I would like to provide a browser with a file download where I set the filename using XQuery. In this example I set the filename to 'example.txt'.

The output fiename is: 'docmaker' and this is not what I want it to be.

What is the correct header configuration to accomplish this?

declare 
%roxy:params("ID=xs:number")
function strlf:get(
$context as map:map,
$params  as map:map
) as document-node()*
{
map:put($context, "output-types", "application/csv"),
map:put($context, "Content-Disposition", 'attachment; filename="example.txt"'),
xdmp:set-response-code(200, "OK"),
    document {
          try {
              let $id := map:get($params,"ID")

              let $query := 
                if (fn:empty($id)) 
                then ()
                else cts:element-range-query(xs:QName("jbasic:ID"),"=",(fn:number($id)))

                for $doc in cts:search(fn:doc(), cts:and-query((cts:directory-query("/app/docmaker/"),$query)), ('unfiltered'))

                return $doc//jbasic:Text/text()

          }
          catch ($e) {
            element error { $e/error:message }
          }
    }
};  

回答1:


Looking at the documentation, the Content-Disposition header, nor any other custom header is supported from within REST extensions:

http://docs.marklogic.com/guide/rest-dev/extensions#id_84661

I don't see other ways around this either. The built-in documents endpoint doesn't provide a download feature of its own, and transforms go through the same framework, so that won't work either.

I'd recommend filing an RFE. That will probably not be helpful for you personally (you'll have to wait for one of the next releases), but may be useful for others in the future..

**UPDATE**

@mblakele's suggestion works, below a working example. I'm reluctant recommending it though. The add-response-header works, but the set-response-code doesn't. The REST-API will override it. The same could happen in future with the add-response-header call..

xquery version "1.0-ml";

module namespace ext = "http://marklogic.com/rest-api/resource/download";

declare default function namespace "http://www.w3.org/2005/xpath-functions";

declare namespace roxy = "http://marklogic.com/roxy";
declare namespace xs = "http://www.w3.org/2001/XMLSchema";

declare option xdmp:mapping "false";

declare
%roxy:params("ID=xs:number")
function ext:get(
  $context as map:map,
  $params  as map:map
) as document-node()*
{
  map:put($context, "output-types", "application/csv"),
  xdmp:add-response-header("Content-Disposition", 'attachment; filename="example.txt"'),
  xdmp:set-response-code(300, "OK"),
  document {
    try {
      doc()[1]
    } catch ($e) {
      element error { $e/error:message }
    }
  }
};

HTH!




回答2:


Instead of calling map:put, try calling https://docs.marklogic.com/xdmp:add-response-header directly. There's probably no need to set the response code: it should default to 200 OK unless there's an error.

I'm not sure exactly how roxy handles that $context item, but I don't see any code that would transform it into response headers automatically.




回答3:


This looks like a Roxy app, not sure if thats using the ML Rest extensions. I would post a question to the Roxy site ...

http://developer.marklogic.com/code/roxy

Or to the MarkLogic general mailing list.

MarkLogic Developer Discussion

Roxy is a developer product not a official MarkLogic product.

If writing a "pure" HTTP App then your technique would work. I dont know what other features of Roxy you need, can you make this particular endpoint a pure HTTP endpoint without changing the rest ?



来源:https://stackoverflow.com/questions/24606676/download-file-filename

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!