为什么在Node JS中对xmlhttprequest post命令的响应是未定义的

时间:2016-10-24 21:03:37

标签: javascript node.js xmlhttprequest alexa alexa-voice-service

我正在尝试使用xmlhttprequest向URL发送请求并使用Node js运行js文件。但对它的反应是未定义的。当我使用CURL命令发布相同的数据时,我得到了适当的响应。为什么在nodejs和xmlhttprequest的情况下它不起作用。

这是我写的代码。文件名是test.js

   'use strict';


var readlineSync = require('readline-sync');
var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var urlopen =require("openurl");


var clientId = "amzn1.application-oa2-client.775a44579eaf461b92db3d1a4cb23a5a";

var deviceId = "Test_device1";
var deviceSerialNumber = 123;
var redirectUri = "https://localhost:9745/authresponse";
var responseType ="code";

var clientSecret = "29a6520d97d11d640e030786e133ccec9ead67005aaa45c212e72e10b00900ff";
promptUserLogin();


sleep(10000);

function sleep(milliseconds) {
  var start = new Date().getTime();
  for (var i = 0; i < 1e7; i++) {
    if ((new Date().getTime() - start) > milliseconds){
      break;
    }
  }
}


var Urlcode = readlineSync.question('enter the code ');

var proceed = readlineSync.question('proceed with execution?');
if(proceed){
  getTokenFromCode(Urlcode); 
}
function promptUserLogin() {


    const scope = 'alexa:all';
    const scopeData = {
        [scope]: {
          productID: deviceId,
          productInstanceAttributes: {
            deviceSerialNumber: deviceSerialNumber
          }
        }
      };
const authUrl = 'https://www.amazon.com/ap/oa?client_id=' + clientId + '&scope=' + encodeURIComponent(scope) + '&scope_data=' + encodeURIComponent(JSON.stringify(scopeData)) + '&response_type=' + responseType + '&redirect_uri=' + encodeURI(redirectUri);
        console.log("abhi avs.js promptUserLogin newWindow");
        urlopen.open(authUrl);
  }


function getTokenFromCode(CODE) {

    return new Promise((resolve, reject) => {
      if (typeof CODE !== 'string') {
        const error = new TypeError('`code` must be a string.');
        this._log(error);
        return reject(error);
      }


      const grantType = 'authorization_code';
      var postData = 'grant_type=' + grantType + '&code=' + CODE + '&client_id=' + clientId + '&client_secret=' + clientSecret + '&redirect_uri=' + encodeURIComponent(redirectUri);

      const url = 'https://api.amazon.com/auth/o2/token';
      const xhr = new XMLHttpRequest();
      xhr.open('POST', url, true);
      xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
      xhr.onload = (event) => {
        let response = xhr.response;
        response = JSON.parse(xhr.response);

        const isObject = response instanceof Object;
        const errorDescription = isObject && response.error_description;
        if (errorDescription) {
          const error = new Error(errorDescription);
          console.log(error);
          return reject(error);
        }
        const token = response.access_token;
        const refreshToken = response.refresh_token;
        const tokenType = response.token_type;
        const expiresIn = response.expiresIn;

        //this.setToken(token)
        //this.setRefreshToken(refreshToken)

        //this.emit(AVS.EventTypes.LOGIN)
        console.log('abhi avs.js Logged in.');
        resolve(response);
      };
     xhr.onerror = (error) => {
        this._log(error);
        reject(error);
      };
      xhr.send(postData);
    });
  }

我在命令节点test.js的终端中运行它。一旦我们运行它,它将打开亚马逊登录页面,我们将被重定向到带有代码的URL。 https://localhost:9745/authresponse?code=ANcUMLaDrkMtCwUSrIqc&scope=alexa%3Aall

这里的代码是ANcUMLaDrkMtCwUSrIqc。将此字符串作为值传递并输入1以执行后续步骤。 那么它会给出错误

未定义 ^

SyntaxError:意外的令牌u     at Object.parse(native)     在xhr.onload(/home/saiabhi/Avs/avs_test.js:100:25)     at dispatchEvent(/home/saiabhi/Avs/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:591:25)     at setState(/home/saiabhi/Avs/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:614:14)     在IncomingMessage。 (/home/saiabhi/Avs/node_modules/xmlhttprequest/lib/XMLHttpRequest.js:447:13)     在emitNone(events.js:72:20)     在IncomingMessage.emit(events.js:166:7)     at endReadableNT(_stream_readable.js:913:12)     at nextTickCallbackWith2Args(node.js:442:9)     at process._tickCallback(node.js:356:17)

参考链接:https://miguelmota.com/blog/alexa-voice-service-authentication/
    当我使用curl命令运行相同的值时,它工作得很好。

curl -X POST --data "grant_type=${GRANT_TYPE}&code=${CODE}&client_id=${CLIENT_ID}&client_secret=${CLIENT_SECRET}&redirect_uri=${REDIRECT_URI}" https://api.amazon.com/auth/o2/token


what am i doing wrong. please let me know.

1 个答案:

答案 0 :(得分:1)

你的代码不干净。我不能说它有效..但首先,我建议改变

 xhr.response

 xhr.responseText;

当你致电承诺时,我总是建议通过链 catch 完成它,因为你可以丢失错误

&#13;
&#13;
'use strict';

var XMLHttpRequest = require("xmlhttprequest").XMLHttpRequest;
var clientId = "amzn1.application-oa2-client.775a44579eaf461b92db3d1a4cb23a5a";
var deviceId = "Test_device1";
var deviceSerialNumber = 123;
var redirectUri = "https://localhost:9745/authresponse";
var Urlcode = "ANcUMLaDrkMtCwUSrIqc";
var clientSecret = "29a6520d97d11d640e030786e133ccec9ead67005aaa45c212e72e10b00900ff";

getTokenFromCode(Urlcode)
    .then(function(result){
        console.log(result);
    })
    .catch(function (error) {
        console.log(error);
    });


function getTokenFromCode(CODE) {

    return new Promise((resolve, reject) => {
        if (typeof CODE !== 'string') {
            const error = new TypeError('`code` must be a string.');
            this._log(error);
            return reject(error);
        }

        const grantType = 'authorization_code';
        var postData = 'grant_type=' + grantType + '&code=' + CODE + '&client_id=' + clientId + '&client_secret=' + clientSecret + '&redirect_uri=' + encodeURIComponent(redirectUri);

        const url = 'https://api.amazon.com/auth/o2/token';
        const xhr = new XMLHttpRequest();
        xhr.open('POST', url, true);
        xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=UTF-8');
        xhr.onload = () => {
            let response = xhr.responseText;
            console.log(response);
            response = JSON.parse(response);
            const isObject = response instanceof Object;
            const errorDescription = isObject && response.error_description;
            if (errorDescription) {
                const error = new Error(errorDescription);
                console.log(error);
                return reject(error);
            }
            const token = response.access_token;
            const refreshToken = response.refresh_token;
            const tokenType = response.token_type;
            const expiresIn = response.expiresIn;
            this.setToken(token)
            this.setRefreshToken(refreshToken)

            this.emit(AVS.EventTypes.LOGIN)
            resolve(response);
        };
        xhr.onerror = (error) => {
            this._log(error);
            reject(error);
        };
        xhr.send(postData);
    });
}
&#13;
&#13;
&#13;