Я получаю POST-запрос от приложения Unity в формате x-form на мой веб-сервер NodeJ.
Я использую app.use(bodyParser.urlencoded({ extended: true}))
для анализа содержимого. Но req.body
возвращает два объекта, проблема в том, что я не могу получить доступ к свойству отдельного свойства, поскольку они не обернуты ни в массив, ни в объект.
Вкл. console.log(req.body)
Я получаюследующий результат
{ sessionId: '5ujgp6vwk1pivth4', gameId: '1', level: '0', score: '0' }
{ sessionId: '5ujgp6vwk1pivth4', gameId: '2', level: '0', score: '0' }
Я хочу знать, какой это тип данных и как я смогу получить доступ к определенному свойству, предположим, что если я сделаю console.log(req.body.sessionId)
, я получу
5ujgp6vwk1pivth4
5ujgp6vwk1pivth4
Даже если я пытаюсь вставить его в массив, я все равно получаю тот же результат.
Я пытаюсь извлечь эти объекты в массив, чтобы мне было легче получить к ним доступ.
Сценарий для маршрутов Express:
const express = require('express')
const path = require('path')
const hbs = require('hbs')
const bodyParser = require('body-parser')
const viewsRouter = require('./routers/views')
const apiRouter = require('./routers/api')
const cookieParser = require('cookie-parser')
require ('./db/mongoose')
const app = express()
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true}))
app.use(cookieParser())
const publicDirectoryPath = path.join(__dirname,'../public')
app.use(express.static(publicDirectoryPath))
const viewsPath = path.join(__dirname,'../templates/views')
const partialsPath = path.join(__dirname,'../templates/partials')
hbs.registerPartials(partialsPath)
hbs.registerHelper('ifCond', function(v1, v2, options) {
if(v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
hbs.registerHelper("math", function(lvalue, operator, rvalue, options) {
lvalue = parseFloat(lvalue);
rvalue = parseFloat(rvalue);
return {
"+": lvalue + rvalue,
"-": lvalue - rvalue,
"*": lvalue * rvalue,
"/": lvalue / rvalue,
"%": lvalue % rvalue
}[operator];
});
app.use(viewsRouter)
app.use(apiRouter)
// For any of the un-handled routes
app.get('*',(req,res)=>{
res.render('error')
})
//Setting up the CORS functionality in Express for Making AJAX calls
app.use(function(req, res, next) {
res.header("Access-Control-Allow-Origin", "*");
res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
next();
});
app.set('views',viewsPath)
app.set('view engine','hbs')
app.listen(80,()=>{
console.log('Server Started on Port 80')
})
Маршрут, отвечающий за конкретный POST,
apiRouter.post('/api/updateScore/',async(req,res)=>{
console.log(req.body)
})
Клиентский скрипт:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine;
using UnityEngine.Networking;
using System.Collections;
using UnityEngine.SceneManagement;
using System.Text;
public class ScoreSender : MonoBehaviour {
public Authentication authentication;
public static readonly string scoreUrl = "https://eyenet.pythonanywhere.com/scores/";
public static ScoreSender instance;
public string Address = "127.0.0.1:8000";
// Use this for initialization
void Start () {
instance = this;
}
// Update is called once per frame
void Update () {
}
public void sendScore(int gameId, int level)
{
}
public void sendScore(string gameId, int level, int score)
{
string loginURL = Address+ "/api/updateScore/";
WWWForm form = new WWWForm();
form.AddField( "sessionId", authentication.session );
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW(loginURL, rawData, headers);
}
// StartCoroutine(WaitForRequest(www));
public void saveScore(string gameId, int nextlevel, int score)
{
// get session id
string sessionCode = authentication.session;
// get score array
int noOfGames = PlayerPrefs.GetInt("totalGames",0);
// get or create score, level, nextlevel arrays
int gid = int.Parse(gameId);
//
int[] scoreArray = PlayerPrefsX.GetIntArray(sessionCode+"scores",0,noOfGames+1);
int[] nextLevelsArray = PlayerPrefsX.GetIntArray(sessionCode+"nextLevels",0,noOfGames+1);
nextLevelsArray[gid] = nextlevel;
scoreArray[gid] = score;
PlayerPrefsX.SetIntArray(sessionCode+"scores",scoreArray);
PlayerPrefsX.SetIntArray(sessionCode+"nextLevels",nextLevelsArray);
PlayerPrefsX.SetIntArray("gameLevels",nextLevelsArray);
Debug.Log("saved score and nextLevels offline");
}
//for sending score to the cloud
public void uploadScore()
{
//testing
//StartCoroutine(scoreSend(authentication.session,"1",45,34));
syncScore(authentication.session);
}
//for online sessions only
void syncScore(string sessionId)
{
Debug.Log("We are syncing the score for this session");
int noOfGames = PlayerPrefs.GetInt("totalGames",0);
int[] currentGamePlays = PlayerPrefsX.GetIntArray(sessionId+"currentGamePlays",0,noOfGames);
int[] scoreArray = PlayerPrefsX.GetIntArray(sessionId+"scores",0,noOfGames+1);
int[] nextLevelsArray = PlayerPrefsX.GetIntArray(sessionId+"nextLevels",0,noOfGames+1);
for(int i=0;i<noOfGames+1;i++)
{
if(currentGamePlays[i]==1) //if the game is played in this session
{
StartCoroutine( scoreSend(sessionId,""+i,nextLevelsArray[i],scoreArray[i]));
Debug.Log("score:"+scoreArray[i]);
Debug.Log("level:"+nextLevelsArray[i]);
}
}
}
public int noOfScores=0;
public void syncOfflineScore(int num,string actualId)
{
string sessionId = "offlineSession"+num;
int noOfGames = PlayerPrefs.GetInt("totalGames",0);
int[] currentGamePlays = PlayerPrefsX.GetIntArray(sessionId+"currentGamePlays",0,noOfGames+1);
int[] scoreArray = PlayerPrefsX.GetIntArray(sessionId+"scores",0,noOfGames+1);
int[] nextLevelsArray = PlayerPrefsX.GetIntArray(sessionId+"nextLevels",0,noOfGames+1);
for(int i=0;i<noOfGames+1;i++)
{
if(currentGamePlays[i]==1) //if the game is played in this session
{
noOfScores++;
}
}
for(int i=0;i<noOfGames+1;i++)
{
if(currentGamePlays[i]==1) //if the game is played in this session
{
StartCoroutine( offlineScoreSend(actualId,""+i,nextLevelsArray[i],scoreArray[i]));
Debug.Log("score:"+scoreArray[i]);
Debug.Log("level:"+nextLevelsArray[i]);
}
}
}
//working fine
IEnumerator scoreSend(string sessionId,string gameId,int nextlevel, int score)
{
string scoreUrl = authentication.Address+ "/api/updateScore/";
WWWForm form = new WWWForm();
form.AddField( "sessionId", sessionId );
form.AddField( "gameId", gameId );
form.AddField( "level", nextlevel);
form.AddField( "score", score);
Dictionary<string, string> headers = form.headers;
//Dictionary<string, string> headers = new Dictionary<string, string>();
//headers.Add("Content-Type", "application/json");
byte[] rawData = form.data;
WWW www = new WWW(scoreUrl, rawData, headers);
WWW data =www;
yield return data;
if(data.error!=null)
{
Debug.Log (data.error);
if(data.error == "Cannot connect to destination host")
{
}
}
else
{
Debug.Log(data.text);
ServerResponse res = JsonUtility.FromJson<ServerResponse>(data.text);
if(res.status==0)
{
Debug.Log("Updated score");
}
else
{
Debug.Log("Got an error");
}
}
}
//test it
IEnumerator offlineScoreSend(string sessionId,string gameId,int nextlevel, int score)
{
string scoreUrl = authentication.Address+ "/api/updateScore/";
WWWForm form = new WWWForm();
form.AddField( "sessionId", sessionId );
form.AddField( "gameId", gameId );
form.AddField( "level", nextlevel);
form.AddField( "score", score);
Dictionary<string, string> headers = form.headers;
byte[] rawData = form.data;
WWW www = new WWW(scoreUrl, rawData, headers);
WWW data =www;
yield return data;
if(data.error!=null)
{
Debug.Log (data.error);
if(data.error == "Cannot connect to destination host")
{
}
}
else
{
Debug.Log(data.text);
ServerResponse res = JsonUtility.FromJson<ServerResponse>(data.text);
if(res.status==0)
{
Debug.Log("Updated score");
noOfScores--;
if(noOfScores==0)
{
authentication.syncOfflineSessionsDataComplete();
}
}
else
{
Debug.Log("Got an error");
}
}
}
}