Alexa Skill执行Ajax请求后无响应问题求助
Hey there, let's break down why your skill goes silent once you add that AJAX call, and how to fix it.
First, let's recap your code examples for clarity:
Working Code
var app = new Alexa.app('appName'); // ... app.intent('marcopolo', { 'slots': {}, 'utterances': ['marco'] }, function(request, response){ console.log('marco worked'); response.say('polo').shouldEndSession(false).send(); }); // Alexa回复:polo // 日志显示:marco worked
Broken Code (With AJAX)
var app = new Alexa.app('appName'); // ... app.intent('marcopolo', { 'slots': {}, 'utterances': ['marco'] }, function(request, response){ console.log('marco started'); return ajax(...
The Root Cause
Alexa expects your intent handler to explicitly send a response using response.send() before the function exits. When you add an AJAX call, you're introducing an asynchronous operation—the AJAX request runs in the background while the intent handler function finishes immediately. Since response.send() never gets called (the AJAX hasn't completed yet), Alexa waits for a response until it times out, resulting in no output to the user.
Fixes to Try
You need to ensure response.send() is only called after the AJAX operation completes. Here are two common approaches:
1. Use AJAX Callbacks (Traditional Approach)
Leverage the AJAX success/error callbacks to send the response once the request finishes:
var app = new Alexa.app('appName'); app.intent('marcopolo', { 'slots': {}, 'utterances': ['marco'] }, function(request, response){ console.log('marco started'); ajax({ url: 'your-api-endpoint', method: 'GET', success: function(data) { // Do something with the returned data if needed console.log('AJAX succeeded:', data); response.say('polo! AJAX worked').shouldEndSession(false).send(); }, error: function(error) { console.error('AJAX failed:', error); // Send an error response to the user response.say('Oops, I had trouble connecting to the service').shouldEndSession(true).send(); } }); });
2. Use Async/Await (Modern Approach)
If you're using a promise-based HTTP library like axios (or you can wrap your AJAX call in a Promise), async/await makes the code cleaner and easier to read:
var app = new Alexa.app('appName'); // Mark the handler as async app.intent('marcopolo', { 'slots': {}, 'utterances': ['marco'] }, async function(request, response){ console.log('marco started'); try { // Wait for the AJAX (axios) request to complete const responseData = await axios.get('your-api-endpoint'); console.log('Got data:', responseData); response.say('polo! Got the data').shouldEndSession(false).send(); } catch (error) { console.error('AJAX failed:', error); response.say('Sorry, something went wrong').shouldEndSession(true).send(); } });
Key Takeaways
- Never let an intent handler finish before sending a response, especially when using async operations.
- Always tie
response.send()to the completion of your async task (via callbacks, Promises, or async/await). - Don't forget error handling—your skill should still send a meaningful response if the AJAX call fails.
内容的提问来源于stack exchange,提问作者BishopZ

