Problems with receiving 'utf-8' from clien

2019-07-30 08:15发布

问题:

I am trying to create a 2-way communication between server and client using Flask and socket.io.

Everything works fine until server receives utf-8 string from client, which gets garbled. Sending from server to client works fine, and prior to sending from client to server, the client prints the message correctly.

Here is some code that reproduces the problem:

app.py:

import flask
from flask_socketio import SocketIO, emit, disconnect

import json

app = flask.Flask(__name__)
socket_io = SocketIO(app)

@socket_io.on('pull')
def socket_io_handle_pull():
    json_msg = {
        'msg': "abcćčddžđefghijklmnnjoprsštuvzž"
    }
    print("Pushing", json_msg)

    socket_io.emit('response', json_msg)

@socket_io.on('push')
def socket_io_handle_push(json_msg):
    print("Pushed:", json_msg)

@socket_io.on('disconnect')
def socket_io_handle_disconnect():
    disconnect()

@app.route('/')
def root():
    return flask.render_template(
        'index.html'
    )

if __name__ == '__main__':
    socket_io.run(app)

index.html:

<!DOCTYPE html>
<html>
  <head>
    <script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/socket.io/1.3.6/socket.io.min.js"></script>
  </head>
  <body>
    <script type="text/javascript">
      var socket = io.connect('http://' + document.domain + ':' + location.port);

      socket.on('response', json => {
        socket.emit('push', json);
      })

      socket.emit('pull');
    </script>
  </body>
</html>

Output:

Pushing {'msg': 'abcćčddžđefghijklmnnjoprsštuvzž'}
Pushed: {'msg': 'abcÄ\x87Ä\x8dddA3Ä\x91efghijklmnnjoprsA!tuvzA3'}

回答1:

You are using the 1.x versions of the Socket.IO client, which had known problems with double-encoding of UTF-8 strings. You should try the 2.x versions which have resolved this issue.



回答2:

It seems that I was getting back a mojibake decoded using latin-1 and encoded with utf-8.

To fix this, I added:

json_str = json_str.encode('latin-1').decode('utf-8')

If you are having this problem, take a look at Miguel's answer.



回答3:

I used servers socket.io js file from reverse proxy by adding socket.io.js end of reverse proxy path like this xxx.com/reverse_proxy_path/socket.io