使用带有参数的NSURLSession(HTTP POST)下载PDF [英] Downloading PDF using NSURLSession (HTTP POST) with parameters

查看:180
本文介绍了使用带有参数的NSURLSession(HTTP POST)下载PDF的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在POST中使用NSURLSession下载PDF文件时遇到了问题.我的下载URL与其他URL不同,因为它的扩展名不是以文件扩展名结尾,并且还需要参数来下载该文件.

它来自ASPX基本服务器,并返回类似的网址

http://example.com/DownloadPDF.aspx?File=ES2Ges%2BUA1CEe1150UF3uUgEDeCEMoIuOrJCbwjzVKCEfA6%2F1zKxycl6MMWcjvtk

如果我必须访问pdf并下载它,我必须提供2个参数 ConfigKeyIDAccessToken.奇怪的是它是POST请求. 由于Alamofire在下载中仅支持GET请求,因此,我必须使用NSURLSession编写自己的自我.但是,我在从代码访问文件时遇到问题,因为它返回带有401的html页面. >

这是html:

401-未经授权:由于凭据无效,访问被拒绝.

服务器错误

401-未经授权:由于凭据无效,访问被拒绝.

您无权使用您提供的凭据查看此目录或页面.

这是我的代码

protocol PDFDownloadAPIProtocol{
    func didSuccessGettingPDF()
    func didFailGettingPDF(err:NSError)
}

class PDFDownloadAPI{

var delegate : InvoicePDFDownloadAPIProtocol

init(delegate: InvoicePDFDownloadAPIProtocol){
    self.delegate=delegate
}

func post(url:String,accessToken:String,configKey :String){
    let url:NSURL = NSURL(string: url)!

    print(url)
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let param = "ConfigKeyID=\(configKey)&AccessToken=\(accessToken)"
    request.HTTPBody = param.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.downloadTaskWithRequest(request) {
        (
        let location, let response, let error) in

        guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
            print("Location Error")
            self.delegate.didFailGettingPDF(error!)
            return
        }

        let urlContents = try! NSString(contentsOfURL: location!, encoding: NSUTF8StringEncoding)

        guard let _:NSString = urlContents else {
            print("Content Error")
            self.delegate.didFailGettingPDF(error!)
            return
        }

        print("Downloaded Content : \(urlContents)")

        self.delegate.didSuccessGettingPDF()
    }

    task.resume()
}

func doDownloadData(url : String,accessToken:String,configKey : String){
    post(url,accessToken: accessToken,configKey : configKey)
}
}

当我尝试使用Postman时,所有工作文件都可以下载,甚至可以从chrome下载文件.因此,我认为我的代码有问题.有帮助吗?

解决方案

有时候,身份验证不仅仅需要POST请求字段.它可能使用cookie或身份验证标头(基于实际凭据).

如果我错了,那么我将检查以下内容:

  • 在将这两个魔术值添加到POST正文之前,请确保正确对其进行了URL编码.
  • 确保您设置了Content-Type标头,以便服务器知道您以x-www-form-urlencoded格式提供正文.
  • 使用Wireshark嗅探该请求,然后查看实际发送的内容.
  • 如果可以,请检查服务器日志.

I have a problem with downloading PDF file using NSURLSession with POST.My download url is different than any other else because it didn't end with file extension name and it also need parameters to download that file.

It's from ASPX base server and return url like that

http://example.com/DownloadPDF.aspx?File=ES2Ges%2BUA1CEe1150UF3uUgEDeCEMoIuOrJCbwjzVKCEfA6%2F1zKxycl6MMWcjvtk

If I have to access the pdf and download it,I have to provide 2 parameters ConfigKeyID and AccessToken.And one thing strange is it was POST request. Since,Alamofire only support GET request in downloading,so,i have to write my own self using NSURLSession.But,I have problem with accessing the file from my code because it return html page with 401.

Here is the html :

401 - Unauthorized: Access is denied due to invalid credentials.

Server Error

401 - Unauthorized: Access is denied due to invalid credentials.

You do not have permission to view this directory or page using the credentials that you supplied.

Here is my code

protocol PDFDownloadAPIProtocol{
    func didSuccessGettingPDF()
    func didFailGettingPDF(err:NSError)
}

class PDFDownloadAPI{

var delegate : InvoicePDFDownloadAPIProtocol

init(delegate: InvoicePDFDownloadAPIProtocol){
    self.delegate=delegate
}

func post(url:String,accessToken:String,configKey :String){
    let url:NSURL = NSURL(string: url)!

    print(url)
    let session = NSURLSession.sharedSession()

    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = "POST"
    request.cachePolicy = NSURLRequestCachePolicy.ReloadIgnoringCacheData

    let param = "ConfigKeyID=\(configKey)&AccessToken=\(accessToken)"
    request.HTTPBody = param.dataUsingEncoding(NSUTF8StringEncoding)

    let task = session.downloadTaskWithRequest(request) {
        (
        let location, let response, let error) in

        guard let _:NSURL = location, let _:NSURLResponse = response  where error == nil else {
            print("Location Error")
            self.delegate.didFailGettingPDF(error!)
            return
        }

        let urlContents = try! NSString(contentsOfURL: location!, encoding: NSUTF8StringEncoding)

        guard let _:NSString = urlContents else {
            print("Content Error")
            self.delegate.didFailGettingPDF(error!)
            return
        }

        print("Downloaded Content : \(urlContents)")

        self.delegate.didSuccessGettingPDF()
    }

    task.resume()
}

func doDownloadData(url : String,accessToken:String,configKey : String){
    post(url,accessToken: accessToken,configKey : configKey)
}
}

When i tried with Postman everything work file and i can even download file from chrome.So,I think there is something wrong with my code.Any Help?

解决方案

Chances are, authentication requires more than just POST request fields. It probably uses either cookies or authentication headers (based on actual credentials).

If I'm wrong, then I'd check the following:

  • Make sure those two magic values are properly URL-encoded prior to adding them into the POST body.
  • Make sure you set the Content-Type header so the server knows that you're providing the body in x-www-form-urlencoded format.
  • Sniff the request with Wireshark and see what is actually getting sent.
  • Check the server logs if you can.

这篇关于使用带有参数的NSURLSession(HTTP POST)下载PDF的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆