2012-05-09 62 views
17

我有一个不寻常的要求。基本上我需要一种方式,当用户点击链接或按钮时,他们会收到PDF。这里最棘手的部分是,除非自定义标题与它发送(否则它认为人退出,并将它们发送到登录界面)的服务器将不处理在所有请求请求具有自定义标头的文件

目前的标题作品不能改变,所以请不要纠缠于它的方式;它将在未来发生变化,并且是我无法控制的内部应用程序。

的选项我已经探讨:

  • 使用的iframe或简单地打开一个新的窗口,带有某种路径,将返回的PDF。这是行不通的,因为我无法为PDF指定所需的标题,并且在到达PDF本身之前将被重定向。
  • 使用表单并提交请求不能工作,因为我不能 添加任何自定义标头的形式(只XHR和插件就可以了,据我所知)。
  • 使用XHR不能工作,因为,虽然它可以添加页眉和 检索文件,有没有办法将它保存在客户端。

这样看来,我在这一点上唯一的选择主要有:

  • 使用某种形式的插件,如Flash或Silverlight的请求文件。
  • 早得多力的需求的变化比预期使头不再需要。

有什么我很想念这里?我希望有人能够验证我的发现或者指出我错过的东西,因为据我所知,在这里我没有什么可以做的。

编辑:这似乎是贴切和证实了我的想法:XMLHttpRequest to open PDF in browser

+2

如何在应用程序和脚本之间添加某种隧道?隧道可以查询应用程序并接收文件,然后在将文件刷新到用户之前设置适当的标题,从而实际触发下载。我不知道这对您的系统是否可行,取决于安全性。 –

+0

隧道不是一个坏主意,虽然我不确定我们可以在这里实现。嗯。谢谢,我会研究它。 – Kris

+1

如果您不支持IE <10(不太可能,对吧?),您可以使用XMLHttpRequest Level 2(XHR2)和Blob URL。下面是一个示例:http://stackoverflow.com/q/9620497另请参阅http://stackoverflow.com/q/6165266和http://www.html5rocks.com/en/tutorials/file/xhr2/ –

回答

13

测试中铬的工作:

function toBinaryString(data) { 
    var ret = []; 
    var len = data.length; 
    var byte; 
    for (var i = 0; i < len; i++) { 
     byte=(data.charCodeAt(i) & 0xFF)>>> 0; 
     ret.push(String.fromCharCode(byte)); 
    } 

    return ret.join(''); 
} 


var xhr = new XMLHttpRequest; 

xhr.open("GET", "/test.pdf"); //I had test.pdf this on my local server 


xhr.addEventListener("load", function(){ 
    var data = toBinaryString(this.responseText); 
    data = "data:application/pdf;base64,"+btoa(data); 
    document.location = data; 
}, false); 

xhr.setRequestHeader("magic", "header"); 
xhr.overrideMimeType("application/octet-stream; charset=x-user-defined;"); 
xhr.send(null); 

您可以更改应用程序/ PDF应用程序/八位字节流具有下载提示。但是从chrome的阅读器下载也很容易。

在Firefox中没有任何反应我猜这是因为我没有插件来处理application/pdf安装。更改为应用程序/八位字节流将提示dl。

与IE浏览器,我想你需要某种形式的VBScript /的ActiveX两轮牛车

。如果文件很大,使用数据的URI可能会崩溃的浏览器,在这种情况下,你可以使用BlobBuilder和对象的URL。

+1

是否可以放置下载的自定义文件名? –

2

链接到.pdf文件代替,而不是像做

<a href="pdf_server.php?file=pdffilename">Download my eBook</a> 

它输出一个自定义标题,打开PDF (二进制安全)并将数据打印到用户的浏览器,然后他们可以选择保存PDF,尽管他们的浏览器设置。该pdf_server.php应该是这样的:

header("Content-Type: application/octet-stream"); 

$file = $_GET["file"] .".pdf"; 
header("Content-Disposition: attachment; filename=" . urlencode($file)); 
header("Content-Type: application/force-download"); 
header("Content-Type: application/octet-stream"); 
header("Content-Type: application/download"); 
header("Content-Description: File Transfer");    
header("Content-Length: " . filesize($file)); 
flush(); // this doesn't really matter. 
$fp = fopen($file, "r"); 
while (!feof($fp)) 
{ 
    echo fread($fp, 65536); 
    flush(); // this is essential for large downloads 
} 
fclose($fp); 

编辑:以头从浏览器(客户端)中添加请求的唯一方法是使用XmlHttpRequest setRequestHeader方法。

xhr.setRequestHeader('custom-header', 'value'); 
+0

这实际上是我的第一个想法,但是,头部必须添加到客户端,因为服务器不会处理任何没有头部的东西。所以,除非我在我的客户端和当前的服务器架构之间使用某些东西,否则不会执行任何服务器端。 – Kris

+0

您不应该添加标头客户端。这应该工作,只要在php文件中的标题之前绝对没有文本。 –

+0

我想你误解了我的要求。生成PDF的服务器需要将自定义标题与所有请求一起发送。如果标题未发送,则假定用户已注销,没有运行服务器端代码,并且该人员被重定向到登录屏幕。我试图证实我的发现,因为我相信在证明一个好的解决方案方面我非常有限。 – Kris

相关问题