2

I have a server side process.php script that echos two chars:

echo chr(127);
echo chr(128);

On the client side, I have a java script (running in an html page with UTF-8 encoding) that posts to the php script and expects a response:

const xhr = new XMLHttpRequest();
// post xhr to php, check for DONE and 200, and get the response
console.log(xhr.responseText);       

For 127, I get the response as a string with one character representing 127 as expected. But for 128 and above it gives me 3 chars, -17, -65 -67. Combed and trawled the net, but nothing. Am quite surprised to not find any info online on transmitting bytes from a server to a client. Am a desktop C++ programmer, btw hence this has me stumped!

ssg
  • 83
  • 6
  • 1
    What character set are you using. What encoding are your pages in? – Krzysztof Krzeszewski Aug 25 '20 at 13:01
  • How and where exactly are you determining what chars it gives you? – deceze Aug 25 '20 at 13:02
  • IIRC `chr(128)` and above are considered "non-printable" characters in PHP – Jay Blanchard Aug 25 '20 at 13:04
  • <> I suppose it is utf-8, which is specified in the head section of my html (nowhere else). – ssg Aug 25 '20 at 13:11
  • <> I pass the resultant response to a C++ function written in emscripten. In that function its easy - parse the response char by char and print out the typecasted integer value. – ssg Aug 25 '20 at 13:14
  • <> Does that mean its technically impossible to have a string passed from a php server to a javascript function that contains these >= 128 chars? In that case, this is a futile exercise? – ssg Aug 25 '20 at 13:17
  • 4
    The single byte value 128 simply is not valid UTF-8 to begin with. (`echo chr(128);` into a page that _is_ proper UTF-8, will only get you a � replacement character shown.) It is very unclear what you are actually trying to _achieve_ here, so the only advice I have as of now, would be to not send arbitrary byte values as _text_. Find _some_ other format to transport whatever data you actually need to transport here. – CBroe Aug 25 '20 at 13:27
  • @CBroe, I am trying to send int and float data from the server to the client. Initially, I sent it in a comma separated text format and parsed it on the client side. This works. Am trying to make it more efficient - one is to avoid the number to string conversion on server and two to avoid parsing commas and converting string to a number on the client. When I do this way between two C++ apps via cout (then reading the pipe), its blazingly fast. – ssg Aug 25 '20 at 13:34

1 Answers1

1

Because you are sending bytes, you need to stop thinking about text and characters. JavaScript is UTF-16 internally, and you'll be transporting text across HTTP from PHP which gets to set it's own encoding.

If you want to parse raw bytes in JavaScript, you'll want to look into the ArrayBuffer. Once you receive your data, you can compose a DataView over it and grab the bytes. If you are 8-bit only, you shouldn't need to worry about endianness, either.

        const xhr = new XMLHttpRequest();
        xhr
            .addEventListener(
                'load',
                () => {
                    const buffer = xhr.response;
                    const view = new DataView( buffer );
                    const byte = view.getUint8( 0 );
                    console.dir( byte );
                }
            );
        xhr.open( 'GET', '/my/end-point' );
        xhr.responseType = 'arraybuffer';
        xhr.send();
Chris Haas
  • 53,986
  • 12
  • 141
  • 274