2015-07-03 67 views
2

我正在使用连接到Express API服务器的ReactJS前端构建应用程序。调用API是使用Ajax进行的。将ReactJS对象作为文件下载

在我的观点之一,一个表加载每行上的“导出”链接。导出链接导致一个React路由,它调用提供CSV文件进行下载的API端点。

如果我直接用有效请求(在React应用程序之外)点击API端点,则会在我的浏览器中启动文件下载。完善!但是,从React页面的导出链接尝试加载发生API调用的视图。该表从视图中消失,并被文件内容替换(目的是为了证明我有数据),但没有下载文件。

我可以强制将响应对象的内容作为文件下载吗? 这可能发生在ajax成功回调? 我做了一个JavaScript的尝试,但我努力与反应虚拟DOM ... 我认为这必须是非常直接,但我很难过。

编辑:@Blex评论帮我解决了这个问题!该解决方案添加到代码片段...

下面是接收数据的JSX:

module.exports = React.createClass({ 

    mixins: [Router.State], 
    getInitialState: function() { 
     return { 
      auth: getAuthState(), 
      export: [], 
      passedParams: this.getParams() 
     }; 
    }, 

    componentDidMount: function(){ 
     $.ajax({ 
      type: 'GET', 
      url: ''+ API_URL +'/path/to/endpoint'+ this.state.passedParams.id +'/export', 
      dataType: 'text', 
      headers: { 
       'Authorization': 'Basic ' + this.state.auth.base + '' 
      }, 
      success: function (res) { 
       // can I force a download of res here? 
       console.log('Export Result Success -- ', res); 
       if(this.isMounted()){ 
        console.log('Export Download Data -- ', res); 
        this.setState({export: res[1]}); 
        // adding the next three lines solved my problem 
        var data = new Blob([res], {type: 'text/csv'}); 
        var csvURL = window.URL.createObjectURL(data); 
        //window.open(csvURL); 
        // then commenting out the window.open & replacing 
        // with this allowed a file name to be passed out 
        tempLink = document.createElement('a'); 
        tempLink.href = csvURL; 
        tempLink.setAttribute('download', 'filename.csv'); 
        tempLink.click(); 
       } 
      }.bind(this), 
      error: function (data) { 
       console.log('Export Download Result Error -- ', data); 
      } 
     }); 
    }, 

    render: function(){ 
     console.log('exam assignment obj -- ', this.state.passedParams.name); 
     var theFileContents = this.state.export; 
      return(
      <div className="row test-table"> 
       <table className="table" > 
        <tr className="test-table-headers"> 
        {theFileContents} // this loads the contents 
        // can I auto download theFileContents? 
        </tr> 
       </table> 
      </div> 
      ) 
    } 
}); 
+1

您可以这样做:http://jsfiddle.net/8f2ah406/这里唯一的问题是文件名和扩展名需要在出现提示时手动设置。否则,只需'window.open(/ * * Ajax请求的URL * /);' – blex

+1

完美的工作!现在我只需要弄清楚如何以音频方式设置文件名。 – fryeguy

+0

相关:http://stackoverflow.com/questions/14964035/how-to-export-javascript-array-info-to-csv-on-client-side/14966131#14966131 –

回答

5

添加基于由@blex评论下面的代码得到了文件下载工作。要在上下文中看到它,请查看问题中的成功回调。

var data = new Blob([res], {type: 'text/csv'}); 
var csvURL = window.URL.createObjectURL(data); 
tempLink = document.createElement('a'); 
tempLink.href = csvURL; 
tempLink.setAttribute('download', 'filename.csv'); 
tempLink.click(); 
+0

谢谢,但不适用于Safari和Firefox – syg