使用Microsoft Graph API发送邮件后无法获取确认响应
问题:使用Microsoft Graph Client发送邮件后无法获取API响应,仅返回ReadableStream
我有一台服务器使用microsoft-graph-client库发送邮件,邮件已成功发送,但Graph API未返回确认响应,仅返回一个可读流:
ReadableStream { locked: false, state: 'readable', supportsBYOB: false }
我的API调用方式
第一种写法(混用await和then):
async function send(client, mailData){ await client.api('/users/sender.email@example.com/sendMail') .post(mailData).then((res) => { console.log(res) }) }
第二种写法(拆分await但无响应):
async function send(client, mailData){ let clientData = await client.api('/users/sender.email@example.com/sendMail') let response = await clientData.post(mailData) console.log(response) }
依赖配置
const { Client } = require('@microsoft/microsoft-graph-client'); const { TokenCredentialAuthenticationProvider } = require('@microsoft/microsoft-graph-client/authProviders/azureTokenCredentials'); const { ClientSecretCredential } = require('@azure/identity');
客户端配置代码
async function getMailer(mailuser) { const credential = new ClientSecretCredential( mailuser.auth.tenant, // Directory (tenant) ID mailuser.auth.user, // Application (client) ID mailuser.auth.pass // Application Secret ); const authProvider = new TokenCredentialAuthenticationProvider(credential, { scopes: ['https://graph.microsoft.com/.default'] }); const client = Client.initWithMiddleware({ debugLogging: true, authProvider }); return client; }
解决方法
根据Microsoft Graph API的设计,sendMail接口在成功时无响应体(返回HTTP 202 Accepted状态码),因此客户端库返回ReadableStream是正常行为。你可以通过以下方式确认请求状态或获取响应元数据:
1. 获取完整响应元数据
使用responseType: 'raw'配置获取包含状态码、响应头的完整响应对象:
async function send(client, mailData){ const rawResponse = await client.api('/users/sender.email@example.com/sendMail') .post(mailData, { responseType: 'raw' }); console.log('请求状态码:', rawResponse.status); // 202表示发送成功 console.log('响应头:', rawResponse.headers); }
2. 修正异步代码写法
client.api()本身不是异步操作,无需await;同时避免混用await和.then(),改用try/catch处理成功/失败:
async function send(client, mailData){ try { await client.api('/users/sender.email@example.com/sendMail').post(mailData); // 执行到此处说明请求已成功(202状态码不会触发catch) console.log('邮件发送成功'); } catch (error) { console.error('邮件发送失败:', error); } }
3. 是否需要换用Axios?
没必要。microsoft-graph-client已封装认证、重试等企业级场景所需的逻辑,更适合长期维护。如果确实需要更直观的响应结构,也可以用Axios直接调用:
const axios = require('axios'); const { ClientSecretCredential } = require('@azure/identity'); async function sendWithAxios(mailuser, mailData) { const credential = new ClientSecretCredential( mailuser.auth.tenant, mailuser.auth.user, mailuser.auth.pass ); const tokenResult = await credential.getToken('https://graph.microsoft.com/.default'); const response = await axios.post( 'https://graph.microsoft.com/v1.0/users/sender.email@example.com/sendMail', mailData, { headers: { 'Authorization': `Bearer ${tokenResult.token}`, 'Content-Type': 'application/json' } } ); console.log('响应状态:', response.status); console.log('响应头:', response.headers); }
内容的提问来源于stack exchange,提问作者Nyoa
相关产品推荐
相关产品推荐

