简体   繁体   中英

Node js can not read the data from curl request via php

I have a problem to read the data I sent via curl request in nodejs. With Postman everything is working properly, but when I try to send request via curl, the api return 500 internal server error and I don't know where is the mistake.

so here is my php code

private function curl($url, $post = false, $header = false)
{
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $url);
    if ($post) {
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post));
    }
    curl_setopt($ch, CURLOPT_HEADER, [
        'Content-Type: application/json',
        'Accept: application/json',
        'Content-Length: ' . mb_strlen(json_encode($post))
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec ($ch);
    curl_close($ch);
    return $response;
}

so now I will share with you the part of nodejs

console.log(req.body)
    let content = req.body.content
    if (!content.length) {
        return res.status(401).send({message: 'content is required'})
    }

and here is the log info

{ '{"content":"content information"}': '' }

2020-08-18T07:27:38.191100+00:00 app[web.1]: TypeError: Cannot read property 'length' of undefined. I don't know where is my mistake, and why I can not read json data on node.js, any help will be appriciate.

your code has 2 notable bugs, and due to PHP's shitty libcurl wrappers, php doesn't even warn you when it notices,

 curl_setopt($ch, CURLOPT_HEADER, [

CURLOPT_HEADER decides whether or not curl should print the received headers along with the body in the output, and it does not even accept arrays, it accepts bools (true/false/0/1), if the api was well-designed, you would get an InvalidArgumentException or TypeError when giving CURLOPT_HEADER anything other than a bool.. but because it's not well designed, php just... "converts the array to a bool" (meaning it will be false if the array is empty, or true otherwise)

what you actually wanted here is CURLOPT_HTTPHEADER , the option for setting HTTP request headers, taking an array.

furthermore,

    'Content-Length: ' . mb_strlen(json_encode($post))

this is wrong, first off mb_strlen() gives you the number of unicode characters in the string, while the Content-Length header is supposed to contain the number of bytes , not the number of unicode characters, so it should be strlen(), not mb_strlen() - secondly, curl will add this header automatically if you don't add it, and curl won't make any typos, and won't calculate the length wrong, so you're better off just letting curl add this header automatically anyway (you calculated the length wrong, curl won't make that mistake, also humans are prone to introducing typos, curl has testsuites to make sure there are no typos in the "Content-Length" header, by comparison, i bet your project does not have testsuites to make sure you didn't introduce any typos in the Content-Length header)

I faced the same problem while trying to do this. This can be solved by using http_build_query($post) instead of json_encode . If you're using express JS make sure you have below handlers.

app.use(express.urlencoded({ extended: false }));
app.use(express.json());

It would appear that you are not properly adding the body to your request in php/curl. As a result, req.body.content is undefined . Accessing a property on undefined throws your error, so you need to check for that possibility in your JS code, but the real issue in your system is that you aren't sending a body in php. Hopefully that helps you get to the root of the problem and you can figure out how to attach the body data to your request from there.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM