首页 > 解决方案 > '400 - Bad Request' when sending GET request with Node.js/got library

问题描述

I'm making an api that communicates with a website to pull player statistics. I've made multiple POST/GET HTTP/1 requests to the server to get a session token and player ID. I then use those values(valid values which I have tested before passing to my function) in my last function to fetch player statistics. The last request is a HTTP/2 GET request. I'm using the got library and vanilla Node. Here is my request:

//THESE ALL HAVE SOME VALUE AFTER I USE SOME OF MY FUNCTIONS; THE FUNCTION I'M
//HAVING TROUBLE WITH IS THE LAST FUNCTION AND IS PASSED VERIFIED NON-NULL VALUES
var session = {
    app_id: '3587dcbb-7f81-457c-9781-0e3f29f6f56a',
    space_id: '5172a557-50b5-4665-b7db-e3f2e8c5041d',
    session_id: null,
    ticket: null,
};


var player = {
    name: null,
    id: null,
    platform: 'uplay',
    kills: null,
    deaths: null,
    rank: null,
};



async function get_player_stats(session, player) {
    var platform = 'PC';
    if (player.platform === 'uplay') {
        platform = 'PC';
    }
    var options = {
        ':authority': 'r6s-stats.ubisoft.com',
        ':method': 'GET',
        ':path': `/v1/current/operators/${player.id}?gameMode=all,ranked,casual,unranked&platform=${platform}&teamRole=attacker,defender&startDate=20200723&endDate=20201120`,
        ':scheme': 'https',
        'authorization': `ubi_v1 t=${session.ticket}`,
        'ubi-appid': session.app_id,
        'ubi-sessionid': session.session_id,
        'content-type': 'application/json',
        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36',
    }
    const url = `https://r6s-stats.ubisoft.com/v1/current/operators/${player.id}?gameMode=all,ranked,casual,unranked&platform=${platform}&teamRole=attacker,defender&startDate=20200723&endDate=20201120`;
    try {
        const response = got(url, {headers: options, http2: true});
        console.log(response);
    }
    catch (err) {
        console.log(err);
    }
}


//FUNCTION CALL
async function fetch(user) {
    var stats_string = await get_player_stats(session, player);
    console.log(stats_string);
}

fetch(username);

Chrome's request header from network log:

:authority: r6s-stats.ubisoft.com
:method: GET
:path: /v1/current/operators/e96ae749-8939-43ed-895f-bf1817e849d9?gameMode=all,ranked,casual,unranked&platform=PC&teamRole=attacker,defender&startDate=20200723&endDate=20201120
:scheme: https
accept: */
accept-encoding: gzip, deflate, br
accept-language: en-US,en;q=0.9
authorization: ubi_v1 t= LONG TOKEN
dnt: 1
expiration: 2020-11-21T09:13:54.804Z
origin: https://www.ubisoft.com
referer: https://www.ubisoft.com/
sec-fetch-dest: empty
sec-fetch-mode: cors
sec-fetch-site: same-site
ubi-appid: 3587dcbb-7f81-457c-9781-0e3f29f6f56a
ubi-sessionid: d78f3306-0e5c-4ac8-ad63-5a711b816f76
user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36

Chrome's Response header from network tools:

access-control-allow-credentials: true
access-control-allow-origin: https://www.ubisoft.com
content-encoding: gzip
content-length: 16969
content-type: application/json
date: Sat, 21 Nov 2020 06:14:47 GMT
status: 200
vary: Origin

What I've tried: I've tried just about everything. I've googled what causes 400 errors, which apparently are mostly user error, and I've looked through my code for days and also looked at Chrome's network activity. I've tried matching Chrome's request header with mine to no avail(my header variable is one of many iterations I've tried--pretty sure I've tried every combination of possible headers). However, sometimes I'll get 400 bad error, or an invalid header response from the server. I've tried using the vanilla Node http2Client.request and that gives me an invalid header/400 as well.

标签: javascriptnode.js

解决方案


好的,终于知道为什么这不起作用了。在我认为我已经尝试了数百万次的地方,我错过了一条细线。在 Chrome 网络活动的请求标头中,有一个expiration. 我需要expiration在标题中设置值来获取数据。所以我需要在我的代码中添加到我的标题中的值是: expiration: 2020-11-21T09:13:54.804Z 未来编辑:到期是 ISO 格式的日期。您可以创建一个日期对象并转换为 ISO:

var time = new Date();
var expiration = time.toISOString();


function someRequest() {
   var options = {
      'expiration': expiration,
   }
}

推荐阅读