Eu tenho um cliente funcional escrito em TypeScript e um servidor web legado escrito em c# . Estou tentando converter o código c# em nós.js/express.
A função de busca do cliente:
export async function myFetch(url : String, data : Object | null) {
const bodyData = JSON.stringify(data);
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: bodyData
}
const fullUrl = serviceBase() + url;
let res;
try {
if (data==null)
res = await fetch(fullUrl);
else
res = await fetch(fullUrl, options);
if (!res.ok) {
throw new Error(`HTTP error: ${res.status}`);
}
return await res.json();
}
catch (error : any) {
AlertError('Web error',error)
}
}
e esta é a interface (em C#) para um dos endpoints do servidor:
[OperationContract]
[WebInvoke(Method = "POST", UriTemplate = "/GetRidesForDate", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
[ServiceKnownType(typeof(List<Ride>))]
IEnumerable<Ride> GetRidesForDate(int date);
Usando isso, GetRidesForDate
retorna resultados corretos.
Na tentativa de nó/expresso eu tenho:
const app = express ();
const port = process.env.PORT || 3000;
app.use(express.json());
app.use(cors());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());
app.listen(port, () => {
console.log("Server Listening on PORT:", port);
});
app.get("/GetRidesForDate/:date", (request: any, response: { json: (arg0: any[]) => void; }) =>
{
console.log('getRidesForDate ' + request.params.date);
getRidesForDate(request,response);
})
mas se eu ligar para o cliente buscar com
rides.value = await myFetch("GetRidesForDate",18800);
o código do servidor nunca chega console.log
, em vez disso, recebo um erro:
SyntaxError: Unexpected token '1', "#" is not valid JSON
at JSON.parse (<anonymous>)
Este 1
é o primeiro dígito dos dados de busca. O cliente apresenta um erro 400 (solicitação incorreta).
Se eu usar um navegador e for para http://localhost:3000/GetRidesForDate/18800
o servidor node/express responde corretamente.
Quais devem ser os parâmetros app.get()
para fazer isso funcionar com meu fetch
comando?
O problema é que o corpo de busca
JSON.stringify(18800)
não é um JSON válido e esse erro de análise vem do analisador de corpo JSON do servidor, daí o400 Bad request
erro (não estou familiarizado com c #, então não tenho ideia de por que não há erro lá ..).Então, você precisa realmente usar um JSON válido:
em vez disso:
usa isto:
e então acesse-o no servidor via
req.body.data
.Além disso, não está claro como você lida com essa solicitação, porque no código de busca do cliente, você parece ter duas solicitações: uma GET e uma POST (que dá o erro), mas nenhuma delas deve funcionar, porque no servidor você tem apenas rota GET que espera
:date
parâmetro, que você parece enviar apenas via corpo na solicitação POST.Então, por que não enviá-lo sempre via body e, se estiver indefinido, configurá-lo para algo padrão e processá-lo.
E se você realmente deseja que essa rota funcione tanto com POST quanto com GET, então você pode usar
app.use("/GetRidesForDate"....
, mas parece não haver propósito para isso, e também, você precisaria adicionar:date
parâmetro na url, e não usarbody
nada, o que é por isso que provavelmente é mais conveniente usar semprereq.body
.Obs: você também pode remover o extra
app.use(bodyParser.json());
, pois você já usaapp.use(express.json());
Experimente isto:
cliente:
servidor: