En mi controlador, las siguientes obras (imprime «oké»)

puts obj.inspect

Pero esto no (renders «aceptar\u00e9»)

render :json => obj

Al parecer, la to_json método escapa los caracteres unicode. Hay una opción para evitar esto?

  • No es un problema de base de datos.

7 Comentarios

  1. 15

    Si usted cavar a través de la fuente de la que finalmente va a venir a ActiveSupport::JSON::Codificación y la de escape método:

    def escape(string)
      if string.respond_to?(:force_encoding)
        string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
      end
      json = string.
        gsub(escape_regex) { |s| ESCAPED_CHARS[s] }.
        gsub(/([\xC0-\xDF][\x80-\xBF]|
               [\xE0-\xEF][\x80-\xBF]{2}|
               [\xF0-\xF7][\x80-\xBF]{3})+/nx) { |s|
        s.unpack("U*").pack("n*").unpack("H*")[0].gsub(/.{4}/n, '\\u\&')
      }
      json = %("#{json}")
      json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
      json
    end

    Los diversos gsub llamadas están obligando a los no-ASCII, UTF-8 a la \uXXXX la notación que estamos viendo. Hexadecimal codificado en UTF-8 debería ser aceptable para nada que los procesos de JSON, pero siempre se podía post-proceso de los JSON (o mono parche modificado en un JSON escaper) para convertir el \uXXXX la notación a raw UTF-8 si es necesario.

    Yo estaría de acuerdo en que al forzar el JSON 7bit-clean es un poco falso, pero hay que ir.

    Respuesta corta: no.

  2. 34

    Para establecer el \uXXXX códigos utf-8:

    json_string.gsub!(/\u([0-9a-z]{4})/) {|s| [$1.to_i(16)].pack("U")}
    • solucionado mi json problema de codificación, muchas gracias
  3. 21

    Se puede prevenir por monkey patching el método mencionado por muu es demasiado corto. Escriba lo siguiente en el archivo de configuración config/inicializadores de los parches.rb (o archivo similar utilizarse para reparar cosas) y reiniciar el proceso de rieles para que el cambio surta efecto.

    module ActiveSupport::JSON::Encoding
      class << self
        def escape(string)
          if string.respond_to?(:force_encoding)
            string = string.encode(::Encoding::UTF_8, :undef => :replace).force_encoding(::Encoding::BINARY)
          end
          json = string.gsub(escape_regex) { |s| ESCAPED_CHARS[s] }
          json = %("#{json}")
          json.force_encoding(::Encoding::UTF_8) if json.respond_to?(:force_encoding)
          json
        end
      end
    end

    Se le advierte que no hay ninguna garantía de que el parche se va a trabajar con las futuras versiones de ActiveSupport. La versión que se utiliza al escribir este post es la 3.1.3.

    • Odio tener que hacer esto, es totalmente resuelto mi Emoji en JSON problemas. Gracias!
    • Sigue siendo un problema en los Rieles 3.1.6, y este parche todavía lo arregla. El equipo de Rails realmente necesita para solucionar este problema en su codificación JSON; emoji no es algo que se va, sobre todo ahora que es parte del estándar Unicode.
    • ver esto de una forma menos miedo solución: stackoverflow.com/questions/683989/…
  4. 12

    Personajes no escapó a unicode con los otros métodos en Rails2.3.11/Ruby1.8 así que he usado el siguiente:

    render :json => JSON::dump(obj)
    • que sí, que funciona en la 1.8 y rails 2.3. bueno.
    • usted es el hombre!
    • Esto también funciona para mí en Rails 4.2.5 / Ruby 2.2.3
    • Trabajó mucho. Gracias!
  5. 9

    Que es la codificación correcta. JSON no requre los caracteres Unicode se pueden escapar, pero es común para JSON bibliotecas para producir un resultado que contiene sólo caracteres ASCII de 7 bits, para evitar posibles problemas de codificación en tránsito.

    Cualquier JSON intérprete será capaz de consumir esa cadena y reproducir el original. Para ver esto en acción, sólo tienes que escribir javascript:alert("ok\u00e9") en su navegador la barra de ubicación.

    • Este chico es de derecho :thumbsup:
  6. 2

    render :json se llame .to_json en el objeto si no es una cadena. Este problema se puede evitar haciendo:

    render :json => JSON.generate(obj)

    Esto por pasar una cadena directamente y por lo tanto evitar la llamada a ActiveSupport del to_json.

    Otro enfoque sería para reemplazar to_json en el objeto a serializar, así que en ese caso, se podría hacer algo como:

    class Foo < ActiveRecord::Base
      def to_json(options = {})
        JSON.generate(as_json)
      end
    end

    Y si uso ActiveModelSerializers, usted puede resolver este problema mediante la invalidación de to_json en su serializador:

    # controller
    respond_with foo, :serializer => MySerializer
    
    # serializer
    attributes :bar, :baz
    
    def to_json(options = {})
      JSON.generate(serializable_hash)
    end
  7. 0

    Tengo una manera muy difícil de resolver este problema. Bueno, si to_json no te permiten tener el código correcto, entonces usted puede intentar escribir :

    render text: tags

    render json: tags o render json: tags.to_json siempre de transferencia automática de la codificación de estilo, pero si usted usa render text:tags, la cadena va a permanecer como está. Y creo que jQuery puede aún reconocer los datos.

Dejar respuesta

Please enter your comment!
Please enter your name here