如何使用 MS Graph 指定将文件上传到 OneDrive 的流
我正在使用 Angular 9 使用 MS Graph 将文件上传到 OneDrive.
I am working with Angular 9 to upload a file to OneDrive using MS Graph.
我上传了一个空文件并上传了一个包含一些虚假内容(数据类型)的文件.我想我没有添加正确的流,
I got so far as to upload an empty file and upload a file with some bogus content (the datatype). I suppose I am not adding the right stream,
我阅读了上传或替换 DriveItem 的内容"和另一堆文档.它说:请求正文的内容应该是要上传的文件的二进制流.
I read "Upload or replace the contents of a DriveItem" and another bunch of documents. it says: The contents of the request body should be the binary stream of the file to be uploaded.
在同一个文档中,在示例(更新现有文件)部分中,它说:
In the same document, in the Example (updating an existing file) section it says:
const stream = The contents of the file goes here.;
let res = await client.api('/me/drive/items/{item-id}/content') .put(stream);
这是无用的.
我从一个对象中获取文件,我使用
I am getting the files from an object, I use
onChangeFilePicker() {
this.upload(this.filePicker.nativeElement.files)
}
它给了我一个 File 对象数组.
which gives me an array of File objects.
然后我尝试了很多不同的方法,最后一个
Then I tried many different ways, the last one
private async uploadFile(graphClient: Client, folderItemId: string, file: File) {
file.arrayBuffer().then((buffer: ArrayBuffer) => {
let u8Buffer = new Uint8Array(buffer)
graphClient
.api(`/me/drive/items/${folderItemId}:/${file.name}:/content`)
.post(u8Buffer.values())
.then(response => {
console.log('ok')
})
.catch(error => {
console.error(error.stack)
})
})
}
它创建了一个包含两个字节的文件.
which creates a file with two bytes.
你知道如何解决它吗?
我找到了解决方案,它是关于编码和图形客户端的.
I found the solution, it was about encoding and the Graph Client.
我跳过了 Graph 客户端,转而使用纯 Graph API 请求.这需要传递Authentication Token,并且需要将请求的Body 放在一起.虽然我得到了类似的结果,但当我将 ArrayBuffer 编码为 UInt8Array 时,这些结果得到了修复,如下所示:
I skipped the Graph Client and went for pure Graph API requests. This requires to pass the Authentication Token, and requires to put together the Body of the request. Though I had similar results, those got fixed when I encoded the ArrayBuffer as a UInt8Array, like this:
获取身份验证令牌:
let graphScopes = new MSALAuthenticationProviderOptions(["Files.ReadWrite.All"]);
let userAgentApplication = new UserAgentApplication( { auth: this.authConfiguration} )
let authProvider = new ImplicitMSALAuthenticationProvider(userAgentApplication, graphScopes );
await authProvider.getAccessToken().
.then(
token => {
let headers = new HttpHeaders({
'Content-Type':'application/json; charset=utf-8',
'Authorization': `Bearer ${token}`
})
然后转换数组缓冲区(如以下建议:Angular 5 HttpClient 发布原始二进制数据)
Then to transform the Array Buffer (as suggested at: Angular 5 HttpClient post raw binary data)
file.arrayBuffer().then( buffer => {
let body = new Uint8Array(buffer)
let uIntBody = body.buffer;
最后发出 HttpClient PUT 请求:
and finally making the HttpClient PUT Request:
async experimentHTTPPostFile(parentId: string, file: File) {
let graphScopes = new MSALAuthenticationProviderOptions(["Files.ReadWrite.All"]);
let userAgentApplication = new UserAgentApplication( { auth: this.authConfiguration} )
let authProvider = new ImplicitMSALAuthenticationProvider(userAgentApplication, graphScopes );
await authProvider.getAccessToken()
.then(
token => {
let headers = new HttpHeaders({
'Content-Type':'application/json; charset=utf-8',
'Authorization': `Bearer ${token}`
})
file.arrayBuffer().then( buffer => {
let body = new Uint8Array(buffer)
let uIntBody = body.buffer;
let url = `${this.MS_GRAPH_BASE_URL}/me/drive/items/${parentId}:/${file.name}:/content`
this.http.put(url, uIntBody, { headers: headers }).toPromise()
.then(response => {
console.log(response)
})
.catch(error => {
console.error(error)
});
})
}
).catch(error => {
console.error(error)
})
}
效果很好,我用 PDF、JPEG 和其他二进制文件进行了测试.
It worked perfectly, I tested with PDF, JPEG and other binary files.
我尝试使用 Graph Client graphClient.api(...).put(...) 对缓冲区进行相同的 UInt8 转换,但并没有解决问题.
I tried doing the same UInt8 transformation of the buffer with the Graph Client graphClient.api(...).put(...), and it does not fix the problem.