Javascript Microsoft Graph';s createUploadSession,内容范围标头错误
我正在尝试将MicrosoftGraphAPI的Javascript Microsoft Graph';s createUploadSession,内容范围标头错误,javascript,fetch,microsoft-graph-api,microsoft-graph-mail,http-content-range,Javascript,Fetch,Microsoft Graph Api,Microsoft Graph Mail,Http Content Range,我正在尝试将MicrosoftGraphAPI的createUploadSession端点与JavaScript SDK一起使用,并尝试用一个刚刚超过3MB的小文件测试上传。每当发送PUT请求时,我都会收到以下错误响应: { "error": { "code": "InvalidContentRangeHeader", "message": "Invalid Content-Rang
createUploadSession
端点与JavaScript SDK一起使用,并尝试用一个刚刚超过3MB的小文件测试上传。每当发送PUT
请求时,我都会收到以下错误响应:
{
"error": {
"code": "InvalidContentRangeHeader",
"message": "Invalid Content-Range header."
}
}
我试图一次发送整个文件,因此请求如下:
const uploadSession=wait客户端
.api(`/me/messages/${messageId}/attachments/createUploadSession`)
.version('beta')
.邮政({
附件:{
attachmentType:“文件”,
名称:attachment.name,
尺寸:附件。尺寸,
},
});
const res=wait fetch(uploadSession.uploadUrl{
方法:'放',
标题:{
“内容类型”:“应用程序/八位字节流”,
“内容范围”:字节0-${attachment.size-1}/${attachment.size}`,
“内容长度”:attachment.size,
},
正文:attachment.contentBytes,
});
const json=await res.json();
返回json;
这里有我遗漏的东西吗?如果我理解正确,那么给出完整的范围应该传递给整个文件。这个问题可能已经过时,因为您使用的是beta版本,而上载会话现在是核心功能的一部分: 无论如何,我还是决定在JS(更准确地说是TypeScript)中分享我的工作实现,因为关于这个主题的大多数问题都是针对
C
在创建了上传会话之后,我没有尝试立即上传整个文件(尽管文档声明这是可能的),但我决定按照他们的建议将整个文件放在4MB的块中
const BYTE_RANGE = 4e6
...
// Send large attachments using an uploadSession
private async _uploadLargeAttachments(
attachments: IMSLargeFileAttachment[],
messageId: string,
clientInstance: Client
): Promise<string[]> {
return Promise.all(
attachments.map(async (attachment) => {
const { attachmentType, name, size } = attachment
const uploadSession: UploadSession = await clientInstance
.api(`/me/messages/${messageId}/attachments/createUploadSession`)
.post({
AttachmentItem: { attachmentType, name, size },
})
if (!uploadSession.uploadUrl) {
// You may also want to throw an error here
return null
}
const fragmentsTotal = Math.ceil(size / BYTE_RANGE)
let i = 0
let bytesRemaining = size
while (i < fragmentsTotal) {
const step = (i + 1) * BYTE_RANGE
const from = i * BYTE_RANGE
const to = bytesRemaining > BYTE_RANGE ? step - 1 : size - 1
bytesRemaining = Math.max(size - step, 0)
const res = await fetch(uploadSession.uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': `${to - from + 1}`,
'Content-Range': `bytes ${from}-${to}/${size}`,
},
body: attachment.body.slice(from, to + 1), // the 2nd slice arg is not inclusive
})
// The final response should have the 'Location' header with a long URL,
// from which you can extract the attachment ID
if (res.status === 201 && res.headers.has('Location')) {
return res.headers.get('Location')
}
i++
}
}).filter((it) => Boolean(it))
)
}
const BYTE_RANGE=4e6
...
//使用上载会话发送大型附件
专用异步上传附件(
附件:IMSLargeFileAttachment[],
messageId:string,
客户端:客户端
):承诺{
回报你的承诺(
附件.map(异步(附件)=>{
常量{attachmentType,name,size}=attachment
const uploadSession:uploadSession=wait clientInstance
.api(`/me/messages/${messageId}/attachments/createUploadSession`)
.邮政({
AttachmentItem:{attachmentType,name,size},
})
如果(!uploadSession.uploadUrl){
//您可能还想在这里抛出一个错误
返回空
}
const fragmentsTotal=Math.ceil(大小/字节\范围)
设i=0
让字节数=剩余大小
而(i字节范围?步骤-1:大小-1
byteslaining=Math.max(大小-步长,0)
const res=wait fetch(uploadSession.uploadUrl{
方法:'放',
标题:{
“内容类型”:“应用程序/八位字节流”,
“内容长度”:“${to-from+1}”,
'Content Range':`bytes${from}-${to}/${size}`,
},
body:attachment.body.slice(from,to+1),//第二个slice参数不包括在内
})
//最后的响应应该有一个长URL的“Location”标题,
//您可以从中提取附件ID
if(res.status==201&&res.headers.has('Location')){
返回res.headers.get('Location')
}
我++
}
}).filter((it)=>布尔值(it))
)
}
希望这能帮助那些在这方面苦苦挣扎的人,因为我想更快地达到他们的目标。这个问题可能已经过时了,因为您使用的是beta版,而上载会话现在是核心功能的一部分:
无论如何,我还是决定在JS(更准确地说是TypeScript)中分享我的工作实现,因为关于这个主题的大多数问题都是针对C
在创建了上传会话之后,我没有尝试立即上传整个文件(尽管文档声明这是可能的),但我决定按照他们的建议将整个文件放在4MB的块中
const BYTE_RANGE = 4e6
...
// Send large attachments using an uploadSession
private async _uploadLargeAttachments(
attachments: IMSLargeFileAttachment[],
messageId: string,
clientInstance: Client
): Promise<string[]> {
return Promise.all(
attachments.map(async (attachment) => {
const { attachmentType, name, size } = attachment
const uploadSession: UploadSession = await clientInstance
.api(`/me/messages/${messageId}/attachments/createUploadSession`)
.post({
AttachmentItem: { attachmentType, name, size },
})
if (!uploadSession.uploadUrl) {
// You may also want to throw an error here
return null
}
const fragmentsTotal = Math.ceil(size / BYTE_RANGE)
let i = 0
let bytesRemaining = size
while (i < fragmentsTotal) {
const step = (i + 1) * BYTE_RANGE
const from = i * BYTE_RANGE
const to = bytesRemaining > BYTE_RANGE ? step - 1 : size - 1
bytesRemaining = Math.max(size - step, 0)
const res = await fetch(uploadSession.uploadUrl, {
method: 'PUT',
headers: {
'Content-Type': 'application/octet-stream',
'Content-Length': `${to - from + 1}`,
'Content-Range': `bytes ${from}-${to}/${size}`,
},
body: attachment.body.slice(from, to + 1), // the 2nd slice arg is not inclusive
})
// The final response should have the 'Location' header with a long URL,
// from which you can extract the attachment ID
if (res.status === 201 && res.headers.has('Location')) {
return res.headers.get('Location')
}
i++
}
}).filter((it) => Boolean(it))
)
}
const BYTE_RANGE=4e6
...
//使用上载会话发送大型附件
专用异步上传附件(
附件:IMSLargeFileAttachment[],
messageId:string,
客户端:客户端
):承诺{
回报你的承诺(
附件.map(异步(附件)=>{
常量{attachmentType,name,size}=attachment
const uploadSession:uploadSession=wait clientInstance
.api(`/me/messages/${messageId}/attachments/createUploadSession`)
.邮政({
AttachmentItem:{attachmentType,name,size},
})
如果(!uploadSession.uploadUrl){
//您可能还想在这里抛出一个错误
返回空
}
const fragmentsTotal=Math.ceil(大小/字节\范围)
设i=0
让字节数=剩余大小
而(i字节范围?步骤-1:大小-1
byteslaining=Math.max(大小-步长,0)
const res=wait fetch(uploadSession.uploadUrl{
方法:'放',
标题:{
“内容类型”:“应用程序/八位字节流”,
“内容长度”:“${to-from+1}”,
'Content Range':`bytes${from}-${to}/${size}`,
},
主体:附件。主体。切片(从,