Forcing download of JSON doc

Thursday, 1 August 2019 · 5 messages
TT
Tim Thompson1 Aug 2019 07:01 #
Hello, I am posting a JSON doc to a RESTXQ function from XForms and trying to set a Content-Disposition header to trigger a file download. Is this possible to do without first saving the JSON doc as a file? Right now, the RESTXQ function returns the correct headers, but does not force a file download dialog. Thanks in advance! Tim
-- Query: xquery version "3.1"; module namespace wrap = "http://example.org/wrap"; declare %rest:path("/wrap") %rest:POST("{$data}") %output:method("json") function wrap:process( $data as node() ) as item()* { let $name := data($data/data/upload/file/@name) let $json := json-to-xml($data/data/upload/file) let $header := ``[attachment; filename="`{$name}`";]`` return ( <rest:response> <http:response status="200" message="OK"> <http:header name="Content-Type" value="application/json"/> <http:header name="Content-Disposition" value="{$header}"/> </http:response> </rest:response>, <map xmlns="http://www.w3.org/2005/xpath-functions"> <map key="Profile"> <array key="resourceTemplates">{$json}</array> <string key="title">Wrapper_Profile</string> <string key="id">Wrapper:Profile:BF2</string> <string key="description">Profile wrapper for resource templates</string> <string key="author">Wrapper</string> <string key="schema"> https://ld4p.github.io/sinopia/schemas/0.0.9/profile.json</string> <string key="date">{current-dateTime()}</string> </map> </map> => xml-to-json() => parse-json() => serialize(map {'method': 'json', 'use-character-maps' : map {'/' : '/'}}) ) }; -- Tim A. Thompson Discovery Metadata Librarian Yale University Library
ML
Marco Lettere1 Aug 2019 09:03 #
Hi Tim, downloading from a browser when posting a form is usually a bit tricky. For me it always ended up with the creation of an artificial <a ...> element with an href crafted from the form parameters and with an attribute download="filename.ext" added to it. Anyway you could try with returning a "forced" application/octet-stream Content-Type header .... M.
Quoted text · Tim Thompson · 75 lines
On 01/08/19 05:00, Tim Thompson wrote: > Hello, > > I am posting a JSON doc to a RESTXQ function from XForms and trying to > set a Content-Disposition header to trigger a file download. Is this > possible to do without first saving the JSON doc as a file? Right now, > the RESTXQ function returns the correct headers, but does not force a > file download dialog. > > Thanks in advance! > Tim > > -- > Query: > > xquery version "3.1"; > > module namespace wrap = "http://example.org/wrap"; > > declare > %rest:path("/wrap") > %rest:POST("{$data}") > %output:method("json") > function wrap:process( > $data as node() > ) as item()* { > let $name := data($data/data/upload/file/@name) > let $json := json-to-xml($data/data/upload/file) > let $header := > ``[attachment; filename="`{$name}`";]`` > return > ( > <rest:response> > <http:response > status="200" message="OK"> > <http:header > name="Content-Type" > value="application/json"/> > <http:header > name="Content-Disposition" > value="{$header}"/> > </http:response> > </rest:response>, > > <map xmlns="http://www.w3.org/2005/xpath-functions"> > <map > key="Profile"> > <array > key="resourceTemplates">{$json}</array> > <string > key="title">Wrapper_Profile</string> > <string > key="id">Wrapper:Profile:BF2</string> > <string > key="description">Profile wrapper for resource > templates</string> > <string > key="author">Wrapper</string> > <string > > key="schema">https://ld4p.github.io/sinopia/schemas/0.0.9/profile.json</string> > <string > key="date">{current-dateTime()}</string> > </map> > </map> => xml-to-json() => parse-json() => serialize(map > {'method': 'json', 'use-character-maps' : map {'/' : '/'}}) > ) > }; > > > -- > Tim A. Thompson > Discovery Metadata Librarian > Yale University Library >
ML
Marco Letterein reply to Tim Thompson, 1 Aug 2019, 16:371 Aug 2019 14:55 #
Maybe using json:serialize() rather than serialize? In general if output:method is set to Json it should be sufficient to return map{} or array{} or alternatively the XML version of a json document without having to explicitly serialize ... M.
Quoted text · Tim Thompson · 105 lines
On 01/08/19 14:36, Tim Thompson wrote: > Thank you, Marco. So, the download issue seems to be with XForms > (XSLTForms) rather than BaseX. If I do a file upload from a plain HTML > form, the file download is triggered correctly. However, even though I > have set "application/json" as the Content-Type, the contents of the > downloaded file are an escaped string rather than a serialized JSON > object: e.g., > > "{\n \"key\": \"value\"\n}" > Is there a way to produce a properly serialized JSON file for download? > > -- > Tim A. Thompson > Discovery Metadata Librarian > Yale University Library > > On Thu, Aug 1, 2019 at 3:03 AM Marco Lettere <m.lettere at gmail.com > <mailto:m.lettere at gmail.com>> wrote: > > Hi Tim, > downloading from a browser when posting a form is usually a bit > tricky. For me it always ended up with the creation of an > artificial <a ...> element with an href crafted from the form > parameters and with an attribute download="filename.ext" added to it. > Anyway you could try with returning a "forced" > application/octet-stream Content-Type header .... > > M. > > On 01/08/19 05:00, Tim Thompson wrote: >> Hello, >> >> I am posting a JSON doc to a RESTXQ function from XForms and >> trying to set a Content-Disposition header to trigger a file >> download. Is this possible to do without first saving the JSON >> doc as a file? Right now, the RESTXQ function returns the correct >> headers, but does not force a file download dialog. >> >> Thanks in advance! >> Tim >> >> -- >> Query: >> >> xquery version "3.1"; >> >> module namespace wrap = "http://example.org/wrap"; >> >> declare >> %rest:path("/wrap") >> %rest:POST("{$data}") >> %output:method("json") >> function wrap:process( >> $data as node() >> ) as item()* { >> let $name := data($data/data/upload/file/@name) >> let $json := json-to-xml($data/data/upload/file) >> let $header := >> ``[attachment; filename="`{$name}`";]`` >> return >> ( >> <rest:response> >> <http:response >> status="200" message="OK"> >> <http:header >> name="Content-Type" >> value="application/json"/> >> <http:header >> name="Content-Disposition" >> value="{$header}"/> >> </http:response> >> </rest:response>, >> >> <map xmlns="http://www.w3.org/2005/xpath-functions"> >> <map >> key="Profile"> >> <array >> key="resourceTemplates">{$json}</array> >> <string >> key="title">Wrapper_Profile</string> >> <string >> key="id">Wrapper:Profile:BF2</string> >> <string >> key="description">Profile wrapper for resource >> templates</string> >> <string >> key="author">Wrapper</string> >> <string >> >> key="schema">https://ld4p.github.io/sinopia/schemas/0.0.9/profile.json</string> >> <string >> key="date">{current-dateTime()}</string> >> </map> >> </map> => xml-to-json() => parse-json() => serialize(map >> {'method': 'json', 'use-character-maps' : map {'/' : '/'}}) >> ) >> }; >> >> >> -- >> Tim A. Thompson >> Discovery Metadata Librarian >> Yale University Library >> >
TT
Tim Thompsonin reply to Marco Lettere, 1 Aug 2019, 09:031 Aug 2019 16:37 #
Thank you, Marco. So, the download issue seems to be with XForms (XSLTForms) rather than BaseX. If I do a file upload from a plain HTML form, the file download is triggered correctly. However, even though I have set "application/json" as the Content-Type, the contents of the downloaded file are an escaped string rather than a serialized JSON object: e.g., "{\n \"key\": \"value\"\n}" Is there a way to produce a properly serialized JSON file for download?
-- Tim A. Thompson Discovery Metadata Librarian Yale University Library
Quoted text · Marco Lettere · 89 lines
On Thu, Aug 1, 2019 at 3:03 AM Marco Lettere <m.lettere at gmail.com> wrote: > Hi Tim, > downloading from a browser when posting a form is usually a bit tricky. > For me it always ended up with the creation of an artificial <a ...> > element with an href crafted from the form parameters and with an attribute > download="filename.ext" added to it. > Anyway you could try with returning a "forced" application/octet-stream > Content-Type header .... > > M. > > On 01/08/19 05:00, Tim Thompson wrote: > > Hello, > > I am posting a JSON doc to a RESTXQ function from XForms and trying to set > a Content-Disposition header to trigger a file download. Is this possible > to do without first saving the JSON doc as a file? Right now, the RESTXQ > function returns the correct headers, but does not force a file download > dialog. > > Thanks in advance! > Tim > > -- > Query: > > xquery version "3.1"; > > module namespace wrap = "http://example.org/wrap"; > > declare > %rest:path("/wrap") > %rest:POST("{$data}") > %output:method("json") > function wrap:process( > $data as node() > ) as item()* { > let $name := data($data/data/upload/file/@name) > let $json := json-to-xml($data/data/upload/file) > let $header := > ``[attachment; filename="`{$name}`";]`` > return > ( > <rest:response> > <http:response > status="200" message="OK"> > <http:header > name="Content-Type" > value="application/json"/> > <http:header > name="Content-Disposition" > value="{$header}"/> > </http:response> > </rest:response>, > > <map xmlns="http://www.w3.org/2005/xpath-functions"> > <map > key="Profile"> > <array > key="resourceTemplates">{$json}</array> > <string > key="title">Wrapper_Profile</string> > <string > key="id">Wrapper:Profile:BF2</string> > <string > key="description">Profile wrapper for resource > templates</string> > <string > key="author">Wrapper</string> > <string > key="schema"> > https://ld4p.github.io/sinopia/schemas/0.0.9/profile.json</string> > <string > key="date">{current-dateTime()}</string> > </map> > </map> => xml-to-json() => parse-json() => serialize(map {'method': > 'json', 'use-character-maps' : map {'/' : '/'}}) > ) > }; > > > -- > Tim A. Thompson > Discovery Metadata Librarian > Yale University Library > > >
TT
Tim Thompsonin reply to Marco Lettere, 1 Aug 2019, 14:551 Aug 2019 17:24 #
Thanks for the tip! By declaring the %output:method("json") annotation AND calling the serialize function, I was basically reserializing the data.
-- Tim A. Thompson Discovery Metadata Librarian Yale University Library
Quoted text · Marco Lettere · 117 lines
On Thu, Aug 1, 2019 at 8:55 AM Marco Lettere <m.lettere at gmail.com> wrote: > Maybe using json:serialize() rather than serialize? > > In general if output:method is set to Json it should be sufficient to > return map{} or array{} or alternatively the XML version of a json document > without having to explicitly serialize ... > > M. > > On 01/08/19 14:36, Tim Thompson wrote: > > Thank you, Marco. So, the download issue seems to be with XForms > (XSLTForms) rather than BaseX. If I do a file upload from a plain HTML > form, the file download is triggered correctly. However, even though I have > set "application/json" as the Content-Type, the contents of the downloaded > file are an escaped string rather than a serialized JSON object: e.g., > > "{\n \"key\": \"value\"\n}" > > Is there a way to produce a properly serialized JSON file for download? > > -- > Tim A. Thompson > Discovery Metadata Librarian > Yale University Library > > On Thu, Aug 1, 2019 at 3:03 AM Marco Lettere <m.lettere at gmail.com> wrote: > >> Hi Tim, >> downloading from a browser when posting a form is usually a bit tricky. >> For me it always ended up with the creation of an artificial <a ...> >> element with an href crafted from the form parameters and with an attribute >> download="filename.ext" added to it. >> Anyway you could try with returning a "forced" application/octet-stream >> Content-Type header .... >> >> M. >> >> On 01/08/19 05:00, Tim Thompson wrote: >> >> Hello, >> >> I am posting a JSON doc to a RESTXQ function from XForms and trying to >> set a Content-Disposition header to trigger a file download. Is this >> possible to do without first saving the JSON doc as a file? Right now, the >> RESTXQ function returns the correct headers, but does not force a file >> download dialog. >> >> Thanks in advance! >> Tim >> >> -- >> Query: >> >> xquery version "3.1"; >> >> module namespace wrap = "http://example.org/wrap"; >> >> declare >> %rest:path("/wrap") >> %rest:POST("{$data}") >> %output:method("json") >> function wrap:process( >> $data as node() >> ) as item()* { >> let $name := data($data/data/upload/file/@name) >> let $json := json-to-xml($data/data/upload/file) >> let $header := >> ``[attachment; filename="`{$name}`";]`` >> return >> ( >> <rest:response> >> <http:response >> status="200" message="OK"> >> <http:header >> name="Content-Type" >> value="application/json"/> >> <http:header >> name="Content-Disposition" >> value="{$header}"/> >> </http:response> >> </rest:response>, >> >> <map xmlns="http://www.w3.org/2005/xpath-functions"> >> <map >> key="Profile"> >> <array >> key="resourceTemplates">{$json}</array> >> <string >> key="title">Wrapper_Profile</string> >> <string >> key="id">Wrapper:Profile:BF2</string> >> <string >> key="description">Profile wrapper for resource >> templates</string> >> <string >> key="author">Wrapper</string> >> <string >> key="schema"> >> https://ld4p.github.io/sinopia/schemas/0.0.9/profile.json</string> >> <string >> key="date">{current-dateTime()}</string> >> </map> >> </map> => xml-to-json() => parse-json() => serialize(map {'method': >> 'json', 'use-character-maps' : map {'/' : '/'}}) >> ) >> }; >> >> >> -- >> Tim A. Thompson >> Discovery Metadata Librarian >> Yale University Library >> >> >> >

⚡Generated with XQuery