【问题标题】:How to disable multiple http(s) request using request package in node js?如何使用节点 js 中的请求包禁用多个 http(s) 请求?
【发布时间】:2017-08-14 06:16:24
【问题描述】:

我正在尝试使用 nodejs 请求包请求 API。为了使用 API,我需要请求一个刷新令牌 API,它将为我提供新的刷新令牌和访问令牌。所以我所做的,如果由于 stat_code == 904 而失败,我会使用请求 API 请求余额我请求新令牌并将其写入文件。

当前访问令牌过期后,我需要使用先前给定的刷新令牌请求新的访问令牌。因此,当我触发请求刷新令牌时,一秒钟内会有 多个请求。一旦有刷新令牌请求进入 API 服务器,刷新令牌就会发生变化。

我对这个问题做了一些研究,我发现唯一关闭的东西是在https://groups.google.com/forum/#!topic/nodejs/kleeRbjiioQ 中,我已经实施了标记agent:false 的解决方案,但仍然有同样的问题。我使用process.hrtime()方便时间参考。

var fs = require("fs");
var cheerio = require('cheerio');
var request = require('request');
var async = require('async');

var username = '';

request_api('john');

//request api function
function request_api(username){
    var username = username;
    var acc_token = fs.readFileSync('authentication/acc_token', 'utf8').replace(/[\n\r]/g, '');
    var datetime = process.hrtime()

    console.log('request balance start '+ datetime)
    console.log('username ='+username);
    console.log('Access token ='+acc_token);

    request({
        url: 'https://sample.api/accbalance?', //URL to hit
        qs: {username:username, channel:'WEB'}, //Query string data
        method: 'GET',
        json: true,
        agent: false,
        pool: false,
        forever: false,
        headers: {
            'Authorization': 'Bearer '+ acc_token , 
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
    }, function (error, response, body) {
         var $ = cheerio.load(body, { xmlMode: true });
         var stat_code = $('ams\\:code').html();

         //Check for error
         if(error){
             return console.log('Error:', error);
         }

         //Check for right status code
         else if(response.statusCode == 401 && stat_code == 904){  
            //904 response timeout 
            console.log('status code '+response.statusCode+ ' and status code'+ stat_code)
            async.waterfall([
                    request_token,
                    request_api(username)
                ], function (error) {
                    if (error) {
                        //handle readFile error or processFile error here
                    }
                });

            }
            else {
                console.log('This is your balance' +body.content.pps.balance);
                console.log('This is your expiry date' +body.content.pps.activestop);
            }
        }
    )
};

//request for API refresh token 
function request_token(){
    var scope = 'SANDBOX'
    var consumer_key = 'key'
    var consumer_secret = 'secret'
    var en_auth_code = new Buffer(consumer_key + ':' + consumer_secret).toString('base64');
    var ref_token = fs.readFileSync('authentication/ref_token', 'utf8').replace(/[\n\r]/g, '');
    var datetime = process.hrtime()

    console.log('request refresh token start '+ datetime)
    console.log('refresh token = '+ ref_token)

    request({
    url: 'https://sample.api/token?', //URL to hit
    qs: {grant_type:'refresh_token', refresh_token:ref_token ,scope:scope }, //Query string data
    method: 'POST',
    json: true,
    agent: false,
    pool: false,
    headers: {
        'Authorization': 'Basic '+ en_auth_code, 
        'Content-Type': 'application/x-www-form-urlencoded'
    },
    }, function(error, response, body){
        if(error) {
            console.log(error);
        } else if(response.statusCode == 200){
            console.log(response.statusCode, body);

            fs.writeFileSync('authentication/acc_token', body.access_token, 'utf8', (err) => {
                if (err) throw err;
                });
            console.log('Access token is saved! '+ body.access_token);

            fs.writeFileSync('authentication/ref_token', body.refresh_token, 'utf8', (err) => {
                if (err) throw err;
                });
            console.log('Refresh token is saved! '+ body.refresh_token);
        } else {
            console.log(response.statusCode+'\n'+body)
        }
    });
};

运行代码后我收到的输出是这样的

request balance start 411093,450855461 //1st api request
username =john
Access token =b212ae55ea6cbb35421679e75f91b0
status code 401 and status code900904
request balance start 411093,814554860  //2nd api request suddenly trigger
username =john
Access token =b212ae55ea6cbb35421679e75f91b0
request refresh token start 411093,816874643
refresh token = 9e52f688428e3c8e8a1a0bb81e48182
200 { expires_in: 86400,
  refresh_token: '7add853045e2d2534e4679d9d719eef9',
  access_token: '414a4d7f2ca9f337a39f8ad2bc412b4' }
Access token is saved! 414a4d7f2ca9f337a39f8ad2bc412b4
Refresh token is saved! 7add853045e2d2534e4679d9d719eef9
status code 401 and status code900904
request balance start 411093,884380787
username =john
Access token =414a4d7f2ca9f337a39f8ad2bc412b4
request refresh token start 411093,885204220
refresh token = 7add853045e2d2534e4679d9d719eef9
200 { 
  expires_in: 86400,
  refresh_token: '68798d3d73b7359b8463d8174ae63',
  access_token: '6cfe65873cf2d46c99616360a76e34ef' }
Access token is saved! 6cfe65873cf2d46c99616360a76e34ef
Refresh token is saved! 68798d3d73b7359b8463d8174ae63
status code 401 and status code900904
request balance start 411093,986352118
username =john
Access token =6cfe65873cf2d46c99616360a76e34ef
request refresh token start 411093,987246880
refresh token = 68798d3d73b7359b8463d8174ae63
200 { 
  expires_in: 86400,
  refresh_token: 'ec4758d42bc960d05cec7174da502764',
  access_token: '2cc27b78c59267f7dee5ac1aed89c7a' }
Access token is saved! 2cc27b78c59267f7dee5ac1aed89c7a
Refresh token is saved! ec4758d42bc960d05cec7174da502764
status code 401 and status code900904
request balance start 411094,154365494
username =john
Access token =2cc27b78c59267f7dee5ac1aed89c7a
request refresh token start 411094,154877335
refresh token = ec4758d42bc960d05cec7174da502764
200 { 
  expires_in: 86400,
  refresh_token: '50a160aceeac3e251d7e287b99ffa',
  access_token: 'fddb51934f5d7de38a8469aefc23' }
Access token is saved! fddb51934f5d7de38a8469aefc23
Refresh token is saved! 50a160aceeac3e251d7e287b99ffa
status code 401 and status code900904
request balance start 411094,248689543
username =john
Access token =fddb51934f5d7de38a8469aefc23
request refresh token start 411094,253453940
refresh token = 50a160aceeac3e251d7e287b99ffa
200 { 
  expires_in: 86400,
  refresh_token: 'd3123ac463e754afd41c7a7065f4b9fa',
  access_token: 'adec764091897b591aecfa3db6d44cc' }
Access token is saved! adec764091897b591aecfa3db6d44cc
Refresh token is saved! d3123ac463e754afd41c7a7065f4b9fa
status code 401 and status code900904
request balance start 411094,392741956
username =john
Access token =adec764091897b591aecfa3db6d44cc
request refresh token start 411094,393600819
refresh token = d3123ac463e754afd41c7a7065f4b9fa
200 { 
  expires_in: 86400,
  refresh_token: 'dfdb3434f4993da5e271570b994d126',
  access_token: '6e53e9746ea9df7a5633f8e96923d5' }
Access token is saved! 6e53e9746ea9df7a5633f8e96923d5
Refresh token is saved! dfdb3434f4993da5e271570b994d126
status code 401 and status code900904
request balance start 411094,478962663
username =john
Access token =6e53e9746ea9df7a5633f8e96923d5
request refresh token start 411094,479420015
refresh token = dfdb3434f4993da5e271570b994d126
200 { 
  expires_in: 86400,
  refresh_token: '5f137193cdac6e2ec13fe38daf6eba70',
  access_token: '96687f1eb16094d53ee08abe1d5d40db' }
Access token is saved! 96687f1eb16094d53ee08abe1d5d40db
Refresh token is saved! 5f137193cdac6e2ec13fe38daf6eba70
This is your prepaid 1329438
This is your expiry date 20180313

我猜同步功能似乎搞混了。顺便说一句,我正在尝试在服务器端实现这一点。 body api服务器的反馈会在json文件中,如下所示。

{
    "resCode": "200",
    "resDesc": "Operation successfully.",
    "content": {
        "pps": {
            "balance": "1440198",
            "activestop": "20180313"
        },
        "paid": "0"
    }
}

成功刷新令牌 body 将在 json 文件中,如下面的代码所示。

{
    "expires_in": 86400,
    "refresh_token": "55379e18b6c6ce1ca6b39a77f15549a3",
    "access_token": "7c6af5939cbecd7ccd83acf57b40bb"
}

感谢您对此的帮助。

【问题讨论】:

    标签: javascript json node.js api http


    【解决方案1】:

    经过将近一周的尝试,我决定将我的代码从使用 request 包更改为使用 request-promise 并且它有效!到目前为止,我没有向 API 服务器发出多个请求,并且代码运行良好。所以我只是想分享代码,希望它也可以帮助其他人。

    var fs = require("fs");
    var cheerio = require('cheerio');
    var request = require('request-promise');
    
    request_api_promise('john')
    .then((result) => {
    console.log(result);
    })
    .catch((error) => {
    console.log(error);
    })
    
    //request for API feature
    function request_api_promise(username) {
    
        let acc_token = fs.readFileSync('authentication/acc_token', 'utf8').replace(/[\n\r]/g, '');
        let datetime = process.hrtime() //Calculate time start
    
        console.log('request balance start =' + datetime)
        console.log('username =' + username);
        console.log('Access token =' + acc_token);
    
        let option = {
        url: 'https://sample.api/accbalance?', //URL to hit
        qs: {
            username: username,
            channel: 'WEB'
        }, //Query string data
        method: 'GET',
        json: true,
        agent: false,
        pool: false,
        forever: false,
        headers: {
            'Authorization': 'Bearer ' + acc_token,
            'Content-Type': 'application/json',
            'Accept': 'application/json'
        },
        resolveWithFullResponse: true
        }
    
        return request(option)
        .then((response) => {
    
             return ({
                    balance: response.body.content.pps.balance,
                    expiry_date: response.body.content.pps.activestop
                }) 
    
        })
        .catch((error) => {
            let $ = cheerio.load(error.response.body, {
                xmlMode: true
            });
            let stat_code = $('ams\\:code').html();
    
            if (error.statusCode == 401 && stat_code == 904) {
    
                console.log('Error: status code ' + error.statusCode + ' stat_code code ' + stat_code)
                return request_token_promise().then(() => request_api_promise(username))
            }
            console.log(error)
        })
    }
    
    //request for API refresh token 
    function request_token_promise() {
        let scope = 'SANDBOX'
        let consumer_key = 'key'
        let consumer_secret = 'secret'
        let en_auth_code = new Buffer(consumer_key + ':' + consumer_secret).toString('base64');
        let ref_token = fs.readFileSync('authentication/ref_token', 'utf8').replace(/[\n\r]/g, '');
        let datetime = process.hrtime()
    
        console.log('request refresh token start = ' + datetime)
        console.log('refresh token = ' + ref_token)
    
        let option = {
        url: 'https://sample.api/token?', //URL to hit
        qs: {
            grant_type: 'refresh_token',
            refresh_token: ref_token,
            scope: scope
        }, //Query string data
        method: 'POST',
        json: true,
        agent: false,
        pool: false,
        headers: {
            'Authorization': 'Basic ' + en_auth_code,
            'Content-Type': 'application/x-www-form-urlencoded'
        },
        resolveWithFullResponse: true
        }
    
        return request(option)
        .then((response) => {
    
            if (response.statusCode == 200) {
                console.log(response.statusCode);
                console.log(response.body);
    
                fs.writeFileSync('authentication/acc_token', response.body.access_token, 'utf8', (err) => {
                    if (err) throw err;
                });
                console.log('Access token is saved! ' + response.body.access_token);
    
                fs.writeFileSync('authentication/ref_token', response.body.refresh_token, 'utf8', (err) => {
                    if (err) throw err;
                });
                console.log('Refresh token is saved! ' + response.body.refresh_token);
    
            } else {
                console.log(response.statusCode);
                console.log(response.body);
            }
        })
    };
    

    下面是输出。

    request balance start =849919,250316580
    username =john
    Access token =8d729facf8cc22fa7ad676c7699d2
    status code 401 anderrorus code 904
    request refresh token start = 849919,417863982
    refresh token = c4e674d0a68ba39f29f476b18bc5ed
    200
    { 
      expires_in: 86400,
      refresh_token: '7c82da4ed9e6fb593e6fadd0c9fd30da',
      access_token: '968472961db5274852afcee7431ed3f5' }
    Access token is saved! 968472961db5274852afcee7431ed3f5
    Refresh token is saved! 7c82da4ed9e6fb593e6fadd0c9fd30da
    request balance start =849919,503441510
    username =john
    Access token =968472961db5274852afcee7431ed3f5
    { balance: '1329438', expiry_date: '20180313' }
    

    但我仍然知道第一组代码有什么问题。如果你们能指出我的第一个代码的问题会很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-03-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-27
      • 1970-01-01
      • 2015-09-01
      相关资源
      最近更新 更多