通过Angular $ http而不是XMLHttpRequest呈现PDF

Ian*_*ton 8 javascript c# angularjs typescript

所以我花了几周时间研究如何通过ajax从服务器获取pdf,然后将其显示给客户端.我需要这样做的原因是用户不能直接在服务器上转到pdf,因为他们不会提供令牌来传递安全性,但我可以使用javascript.使用以下代码,我能够得到我所期望的:

 var xhr = new XMLHttpRequest();
 xhr.open('GET', url, true);
 xhr.responseType = 'arraybuffer';
 xhr.setRequestHeader("token", token.value);
 xhr.onload = function (e) {
    if (this.status == 200) {
       var file = new Blob([this.response], { type: 'application/pdf' });
       var fileURL = URL.createObjectURL(file);
       window.open(fileURL, '_blank');
    }
 };
 xhr.send();
Run Code Online (Sandbox Code Playgroud)

然而,当我尝试以这样的角度做这个确切的事情时(我正在做这个东西的一半,所以两者中的标题匹配):

var config = {
    url: url,
    method: 'GET',
    responseType: 'arraybuffer',
    headers: {
        'Accept':'*/*',
        "token": token.value
    }
}

$http(config)
    .success(function (response) {
        var file = new Blob([response], { type: 'application/pdf' });
        var fileURL = URL.createObjectURL(file);
        window.open(fileURL, '_blank')
    });
Run Code Online (Sandbox Code Playgroud)

以下是两个标题的样子:

GET http://example.com HTTP/1.1
Host: example.com
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/50.0.2661.94 Safari/537.36
token: test
Referer: http://example.com
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8
Run Code Online (Sandbox Code Playgroud)

唯一的区别是xmlhttprequest版本具有Authorization:Negotiate标头,但我可以从服务器的响应中在fiddler中呈现它们.这告诉我来自$ http的'response'与xmlhttprequest中的this.response不同.有人可以告诉我有什么不同以及如何解决它?

我想了很长一段时间,这是一个charset问题,我甚至在通过线路发送它之前使用了base64字节,然后使用atob()将其切换回来,但这似乎没有让它变得更好.似乎$ http版本接受响应并将字节转换为utf8,即使它们不是......我认为我的字节是windows-1252/latin1/ios-8895-1

我说这个的原因是因为我在十六进制编辑器中看到了这个:

btye 85(在服务器上)切换到C2 85的两个字节(在$ http代码之后) http://www.fileformat.info/info/unicode/char/85/charset_support.htm

btye c5(在服务器上)切换到c3 85的两个字节(在$ http代码之后) http://www.fileformat.info/info/unicode/char/c5/charset_support.htm

我甚至尝试编码/解码,如果各种组合无济于事.我真的认为pdf在通过棱角分析时会被破坏,但我不知道如何.

更新1

在服务器端,代码如下所示:

public class LabelController : Controller
{
  //using Microsoft.AspNet.Mvc
  [HttpGet, Route("api/labels/box")]
  public IActionResult BoxLabels(Guid requestId)
  {
    var data = this.getPDF("http://foobar.com/example.pdf");
    Response.Headers.Add("Content-Length", data.Length.ToString());
    Response.Headers.Add("Content-Disposition", "inline; filename=example.pdf");
    return new FileContentResult(data, "application/pdf");
  }

  //using restsharp
  private bytes[] getPDF(url)
  {
    var client = new RestClient
    {
      BaseUrl = new Uri(url),
      Authenticator = new NtlmAuthenticator()
    };

    var request = new RestRequest
    {
      Method = Method.POST,
      Credentials = CredentialCache.DefaultNetworkCredentials,
      RequestFormat = DataFormat.Xml
    };

    var response = client.Execute(request);
    return response.RawBytes;
  }
}
Run Code Online (Sandbox Code Playgroud)

以下是它的样子:http://plnkr.co/edit/R3FiesPk7Os22SMsTTfE没有"No'Access-Control-Allow-Origin'"错误

更新2

以下是网络流量告诉我的内容: 检查ajax电话

以下是使用$ http时pdf的样子:

使用$ http时的空白pdf

Sar*_*hal 1

所以我认为你的问题是浏览器正在执行 CORS 预检,因为你正在执行跨浏览器请求。它将 GET 请求转变为 OPTIONS。

在此输入图像描述

您需要将 OPTIONS 请求添加到您接受的 CORS 选项中。您可能还需要将您的 IP 地址添加到 CORS 选项中接受的来源。

以下是一些有用的链接: http://barnabas.tumblr.com/post/87914971548/the-curse-of-the-cors-preflight-and-how-to-defeat 对如何处理 CORS OPTIONS 预检请求感到困惑