Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在CycleJS中从POST请求获取文件_Javascript_Rxjs_Cyclejs - Fatal编程技术网

Javascript 如何在CycleJS中从POST请求获取文件

Javascript 如何在CycleJS中从POST请求获取文件,javascript,rxjs,cyclejs,Javascript,Rxjs,Cyclejs,我已经编写了一个Spring控制器,它在请求中接受json并响应pdf文件 public ResponseEntity<byte[]> generateResp(...) byte[] gMapRep = Files.readAllBytes(file.toPath()); HttpHeaders httpHeaders = new HttpHeaders(); httpHeaders.setContentType(Medi

我已经编写了一个Spring控制器,它在请求中接受json并响应pdf文件

public ResponseEntity<byte[]> generateResp(...)
     byte[] gMapRep = Files.readAllBytes(file.toPath());

            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.parseMediaType("application/pdf"));

            httpHeaders.setContentDispositionFormData("content-disposition", "filename=report.pdf");
            httpHeaders.setCacheControl("must-relative, post-check=0, pre-check=0");

        return ResponseEntity
                .ok()
                .headers(httpHeaders)
                .body(gMapRep);

下面是一个客户端使用示例,从(模拟的)API中获取值,点击按钮填充隐藏表单,然后将表单提交到服务器脚本,该脚本返回一个PDF文档,该文档被定向到新的浏览器窗口或选项卡:

import Rx from 'rx';
import Cycle from '@cycle/core';
import {div, form, input, button, makeDOMDriver} from '@cycle/dom';

function makeFormDriver (formid, elemid) {
  return function (post$) {
    post$.subscribeOnNext(function (post) {
        document.querySelector(elemid).value = post;
        document.querySelector(formid).submit();
    });
  }
}

function main({DOM}) {
  const buttonClick$ = DOM.select('button#pdf').events('click');
  const api$ = Rx.Observable.of('test.pdf'); // mocked API
  const post$ = buttonClick$.withLatestFrom(api$, (bclick, file) => file);

  const vdom$ = Rx.Observable.of(
    div([
      form('#pdfform', {
        method: 'post', action: 'http://localhost:3000/file',
        target: '_blank', style: 'display: none;'
      }, [input(#filename', {type: 'hidden', name: 'filename'})]),
      button('#pdf', 'PDF')
    ])
  );

  return {
    DOM: vdom$,
    FORM: post$
  };
}

Cycle.run(main, {
  DOM: CycleDOM.makeDOMDriver('#app'),
  FORM: makeFormDriver('#pdfform', '#filename')
});

下面是一个客户端使用示例:


下面是一个服务器端的例子,使用接收发布的数据并返回指定的文档:

import xs from 'xstream';
import Cycle from '@cycle/xstream-run';
import express from 'express';
import bodyParser from 'body-parser';

let server = express();
server.use(bodyParser.urlencoded({ extended: false }))

function makeDownloadDriver (effect) {
  return function (postfile$) {
    let file$ = postfile$.map(body => body.filename)
    file$.addListener({
      next: effect,
      error: function () {},
      complete: function () {}
    })
  }
}

server.use(function (req, res) {

  let postfile$ = xs.of(req)
    .filter(req => 'POST' === req.method && '/file' === req.url)
    .map(req => req.body);

  function main (sources) {
    return {
      postfile: postfile$
    };
  }

  Cycle.run(main, {
    postfile: makeDownloadDriver(file => res.sendFile(file, {root: __dirname})),
  });

});

server.listen(3000);

要查看这些与页面路由器一起工作,请签出。

我已尝试使用window.open()获取响应和订阅响应,但它不工作。我还尝试添加数据:application/pdf,+response.text,它会打开pdf文件,但这里的解析pdf文件有问题。你能发布你的前端代码吗?很难仅仅从XHR(Ajax)的描述就看出哪里出了问题。有必要使用XHR吗?或者你可以简单地通过HTTP发布序列化的JSON数据吗?不,我认为在这种情况下没有必要这样做。HTTP POST我只需要发送对于构建pdf非常重要的数据。
import xs from 'xstream';
import Cycle from '@cycle/xstream-run';
import {div, form, input, button, makeDOMDriver} from '@cycle/dom';

function makeFormDriver (formId, elemId) {
  const form = document.querySelector(formId);
  const elem = document.querySelector(elemId);
  return function (post$) {
    post$.addListener({
      next: function (post) {
        elem.value = post;      // populate form data
        form.submit();          // submit form
      },
      error: function () {},
      complete: function () {}
    });
  }
}

function main(sources) {
  const buttonclick$ = sources.DOM.select('#pdfbutton').events('click');
  const api$ = xs.of('test.pdf');                           // mocked API
  const post$ = buttonclick$.map(bclick => api$).flatten(); // ~ withLatestFrom

  let vtree$ = xs.of(
    div('.pdf', [
      form('#pdfform', {attrs: {
        method: 'post', action: '/file',
        target: '_blank', style: 'display: none;'      // new tab and hide form
      }}, [
        input('#filename', {attrs: {name: 'filename', type: 'input'}}),
      ]),
      button('#pdfbutton', 'view pdf')
    ])
  )

  return {
    DOM: vtree$,
    FORM: post$
  };
}

Cycle.run(main, {
  DOM: makeDOMDriver('.app-container'),
  FORM: makeFormDriver('#pdfform', '#filename')
});
import xs from 'xstream';
import Cycle from '@cycle/xstream-run';
import express from 'express';
import bodyParser from 'body-parser';

let server = express();
server.use(bodyParser.urlencoded({ extended: false }))

function makeDownloadDriver (effect) {
  return function (postfile$) {
    let file$ = postfile$.map(body => body.filename)
    file$.addListener({
      next: effect,
      error: function () {},
      complete: function () {}
    })
  }
}

server.use(function (req, res) {

  let postfile$ = xs.of(req)
    .filter(req => 'POST' === req.method && '/file' === req.url)
    .map(req => req.body);

  function main (sources) {
    return {
      postfile: postfile$
    };
  }

  Cycle.run(main, {
    postfile: makeDownloadDriver(file => res.sendFile(file, {root: __dirname})),
  });

});

server.listen(3000);