0

我正在尝试将文件作为附件上传到我的 Frappe 实例并遇到了几个问题。其中第一个是相关的,并且记录了填充错误:in this question。我把它包括在这里,以防它在某种程度上是我所犯错误的一部分。

我的第二个问题,这个问题的重点是,当我上传附件时,它们似乎已损坏。可以打开一个小的 xml 文件,但大部分是乱码。更大的 PDF 文件甚至无法打开。我的假设是我在使用 base64 编码时犯了某种初学者错误。

从本地 URL 获取数据:

let settingsLocation = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0].appendingPathComponent("SettingsList.plist")
let fileData = try Data.init(contentsOf: settingsLocation)

然后将其传递给以下函数:

    public func attachFileToCloudResource(resourceType: String, resourceName: String, attachment: Data) {
    
    let fileAsString = (attachment.base64EncodedString().replacingOccurrences(of: "+", with: "%2B") + "==")
    
    var request = URLRequest(url: URL(string: FRAPPE_INSTANCE + FRAPPE_METHODS + FRAPPE_UPLOAD_ATTACHMENT)!)

    var components = URLComponents(url: request.url!, resolvingAgainstBaseURL: false)!

    components.queryItems = [
        URLQueryItem(name: FRAPPE_DOCTYPE, value: resourceType),
        URLQueryItem(name: FRAPPE_DOCNAME, value: resourceName),
        URLQueryItem(name: FRAPPE_FILENAME, value: "testFile.xml"),
        URLQueryItem(name: FRAPPE_DATA, value: fileAsString),
        URLQueryItem(name: FRAPPE_PRIVATE, value: "1"),
        URLQueryItem(name: FRAPPE_DECODE_BASE64, value: "1")
    ]

    let query = components.url!.query

    request.httpMethod = "POST"
    request.addValue("token \(API_KEY):\(API_SECRET)", forHTTPHeaderField: "Authorization")
    request.addValue("application/x-www-form-urlencoded", forHTTPHeaderField: "Content-Type")
    request.httpBody = Data(query!.utf8)


    // url session and dataTask send data to server below this point
    }

这可以正常工作,因为我从服务器获得了肯定的响应,并且文件附加到指定的记录 - 但是当文件被下载(通过网络浏览器)时,无论我尝试什么类型的文件,它似乎都已损坏。

任何帮助将非常感激。

4

1 回答 1

0

我能够找到适合我的解决方案。

首先,我使用了一个在线 base64 编码器来编码一个简单的 xml 文件。然后我使用生成的 base64 字符串使用Postman重新创建我的 POST (很棒的工具,只是刚刚发现它)。

这有效,我的文件附加到指定的记录并且没有损坏。

然后,我使用 Postman 生成代码的功能来查看它认为用于文件数据的 base64String 应该是什么样子。我发现所有的“+”字符都被“%2B”替换了。

进一步调查发现,Swift 中的查询项做了一些它自己的百分比编码,但是这个答案解释了为什么“+”字符是有效的,而不是默认情况下的百分比编码。

最终结果是我从原始 base64String 中删除了手动百分比编码:

let fileAsString = attachment.base64EncodedString() + "=="

我在从查询项生成 httpBody 时添加了它:

request.httpBody = Data(query!.replacingOccurrences(of: "+", with: "%2B").utf8)
于 2021-08-19T11:58:35.977 回答