Foros del Web » Programando para Internet » Javascript » Frameworks JS »

Problemas de especificación de charset

Estas en el tema de Problemas de especificación de charset en el foro de Frameworks JS en Foros del Web. Buenas a tod@s, Llevo durante unas horas peleándome con un tema. La situación es la siguiente: Tengo 3 páginas, una principal y 2 cargas por ...
  #1 (permalink)  
Antiguo 06/09/2011, 05:47
 
Fecha de Ingreso: febrero-2010
Mensajes: 22
Antigüedad: 14 años, 2 meses
Puntos: 0
Problemas de especificación de charset

Buenas a tod@s,

Llevo durante unas horas peleándome con un tema. La situación es la siguiente:

Tengo 3 páginas, una principal y 2 cargas por ajax, todas ellas en ASP clásico. Las cargas ajax son para rellenar varios select (el típico de Provincia/Localidad/Código Postal), el problema me surge durante la comunicación con ellas...

Todas mis páginas están perfectamente advertidas que son ISO-8859-1 (también conocido como Windows 1252) con códigos como estos:

<%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
Response.Charset = "iso-8859-1"
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1" />

Y en las respuestas aunque son HTML coloqué esto:
<?xml version="1.0" encoding="ISO-8859-1"?>

He probado también esto:
ajax.setRequestHeader("Accept-Charset", "ISO-8859-1");
ajax.setRequestHeader("Content-Type", "text/xml; charset=iso-8859-1");
ajax.send(null);

El problema está en que cuando solicito las provincias y las localidades no tengo ningún problema, veo las tildes y las "ñ", pero cuando envío la variable del nombre de la localidad para sacar sus códigos postales no me devuelve nada en las SELECT que incluyen tilde o Ñ en todos los navegadores salvo Internet Explorer 8 (que mágicamente en él no tengo problema y sí se realiza toda la comunicación en iso-8859-1). He podido comprobar que es porque al enviarlas, Ajax me lo envía en UTF-8 al servidor web y no conozco ninguna forma de cambiar esto o de transformar algo en UTF-8 a Windows 1252 desde ASP.

Mi base de datos está codificada en ISO-8859-1 y desconozco si es capaz de devolverme los datos en UTF-8 ya que lo intenté pero me daba error (es ASA).

Pongo el código en cualquier caso por si fuese necesario:

Código ASP:
Ver original
  1. <%@LANGUAGE="VBSCRIPT" CODEPAGE="1252"%>
  2. <% Option Explicit %>
  3. <?xml version="1.0" encoding="ISO-8859-1"?>
  4. <% ' Especificamos envío de conjunto de caracteres
  5. Response.Charset = "iso-8859-1"
  6.  
  7. If Request.QueryString("prov") = 99 Or Request.QueryString("prov") = "" Then
  8.     %>
  9.     <input class="singlefield" type="text" name="cp" id="cp" value="" />
  10.     <%
  11.     Response.End
  12. End If
  13.  
  14. If Request.QueryString("loc") = "" Then
  15.     %>
  16.     <input class="singlefield" type="text" name="cp" id="cp" value="" />
  17.     <%
  18.     Response.End
  19. End If
  20.  
  21. Dim SQL, conexion, rsLocalidades, ArrayRecordSet, i, SizeArray
  22.  
  23. ' Conecto y muestro error en caso de no lograr conectar
  24.  
  25. On Error Resume Next
  26.  
  27. 'Abro conexión a BD interna y transacción
  28. Set conexion = CreateObject("ADODB.Connection")
  29.     conexion.ConnectionString="DSN=BD Interna"
  30.     conexion.Open
  31.     conexion.BeginTrans
  32.  
  33. 'Si no logro conectar, reseteo el número de error y conecto a servidor externo
  34. If Err.Number <> 0 Then
  35.  
  36.     On Error GoTo 0
  37.     On Error Resume Next
  38.    
  39.     conexion.ConnectionString="DSN=MeetingPoint"
  40.     conexion.Open
  41.     conexion.BeginTrans
  42.  
  43.     'No se logró conectar a ninguno de los dos, muestro error
  44.     If Err.Number <> 0 Then
  45.         Response.Write("Error, elija de nuevo.")
  46.         Response.End
  47.     End If
  48. End If
  49.  
  50. ' Lanzamos el RecordSet en modo 0, 1, 0 con cursor en local para tratar de reducir su tiempo de ejecución
  51. Set rsLocalidades = Server.CreateObject("ADODB.Recordset")
  52.     rsLocalidades.CursorLocation = 3    'adUseClient
  53.     rsLocalidades.CursorType = 0        'adOpenForwardOnly
  54.     rsLocalidades.LockType = 1          'adLockReadOnly
  55.     SQL = "SELECT DISTINCT(codpostal) FROM codpostloc WHERE provincia = '" & Request.QueryString("prov") & "' AND " & _
  56.           "poblacion = '" & Request.QueryString("loc") & "' ORDER BY 1"
  57.     rsLocalidades.Open SQL, conexion
  58.    
  59.     ' Response.Write(SQL)
  60.        
  61. If Err.Number <> 0 Then
  62.     Response.Write("Error, seleccione localidad de nuevo.")
  63.     conexion.RollbackTrans
  64.     Response.End
  65. End If
  66.  
  67. ' Copio a un array el RecordSet, calculo tamaño máximo de la dimensión 2 (1-columna/2-fila) y cierro conexión
  68. ArrayRecordSet = rsLocalidades.GetRows
  69. SizeArray = UBound(ArrayRecordSet, 2)
  70. ' Response.Write("<br>" & ArrayRecordSet(0,0))
  71. rsLocalidades.Close
  72. conexion.RollbackTrans
  73. conexion.Close
  74.  
  75. On Error Goto 0 %>
  76.  
  77. <% If SizeArray > 0 Or IsArray(ArrayRecordSet) Then %>
  78. <select class="singlefieldcombo" id="cp" name="cp" >
  79.     <% If SizeArray > 0 Then %>
  80. <option value=""></option>
  81.     <% End If %>
  82.     <% For i = 0 To SizeArray %>
  83. <option value="<%=ArrayRecordSet(0, i)%>"><%=ArrayRecordSet(0, i)%></option>
  84.     <%Next %>
  85. </select>
  86. <% End If %>

Muchas gracias y un saludo.
  #2 (permalink)  
Antiguo 07/09/2011, 03:22
 
Fecha de Ingreso: febrero-2010
Mensajes: 22
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: Problemas de especificación de charset

Tras continuar pateándome Google llegué a la conclusión de que no había manera de decirle a Ajax que envíe los datos en otra codificación que no sea UTF8, por ello decidí que lo mejor sería cambiar de UTF8 a iso-8859-1 directamente desde ASP. Como no hay una función concreta que lo haga, encontré algo efectivo y que me funcionó:

Fuente: http://www.codetoad.com/asp_utf8.asp
Código ASP:
Ver original
  1. <%
  2. Option Explicit
  3.  
  4. ' Simple Functions to convert the first 256 characters
  5. ' of the Windows character set from And to UTF-8.
  6.  
  7. ' Written by Hans Kalle for Fisz
  8. ' http://www.fisz.nl
  9.  
  10. 'IsValidUTF8
  11. '  Tells If the string is valid UTF-8 encoded
  12. 'Returns:
  13. '  true (valid UTF-8)
  14. '  false (invalid UTF-8 or not UTF-8 encoded string)
  15. Function IsValidUTF8(s)
  16.   Dim i
  17.   Dim c
  18.   Dim n
  19.  
  20.   IsValidUTF8 = false
  21.   i = 1
  22.   Do While i <= len(s)
  23.     c = asc(mid(s,i,1))
  24.     If c And &H80 Then
  25.       n = 1
  26.       Do While i + n < len(s)
  27.         If (asc(mid(s,i+n,1)) And &HC0) <> &H80 Then
  28.           Exit Do
  29.         End If
  30.         n = n + 1
  31.       Loop
  32.       Select Case n
  33.       Case 1
  34.         Exit Function
  35.       Case 2
  36.         If (c And &HE0) <> &HC0 Then
  37.           Exit Function
  38.         End If
  39.       Case 3
  40.         If (c And &HF0) <> &HE0 Then
  41.           Exit Function
  42.         End If
  43.       Case 4
  44.         If (c And &HF8) <> &HF0 Then
  45.           Exit Function
  46.         End If
  47.       Case Else
  48.         Exit Function
  49.       End Select
  50.       i = i + n
  51.     Else
  52.       i = i + 1
  53.     End If
  54.   Loop
  55.   IsValidUTF8 = true
  56. End Function
  57.  
  58. 'DecodeUTF8
  59. '  Decodes a UTF-8 string to the Windows character set
  60. '  Non-convertable characters are replace by an upside
  61. '  down question mark.
  62. 'Returns:
  63. '  A Windows string
  64. Function DecodeUTF8(s)
  65.   Dim i
  66.   Dim c
  67.   Dim n
  68.  
  69.   i = 1
  70.   Do While i <= len(s)
  71.     c = asc(mid(s,i,1))
  72.     If c And &H80 Then
  73.       n = 1
  74.       Do While i + n < len(s)
  75.         If (asc(mid(s,i+n,1)) And &HC0) <> &H80 Then
  76.           Exit Do
  77.         End If
  78.         n = n + 1
  79.       Loop
  80.       If n = 2 And ((c And &HE0) = &HC0) Then
  81.         c = asc(mid(s,i+1,1)) + &H40 * (c And &H01)
  82.       Else
  83.         c = 191
  84.       End If
  85.       s = left(s,i-1) + chr(c) + mid(s,i+n)
  86.     End If
  87.     i = i + 1
  88.   Loop
  89.   DecodeUTF8 = s
  90. End Function
  91.  
  92. 'EncodeUTF8
  93. '  Encodes a Windows string in UTF-8
  94. 'Returns:
  95. '  A UTF-8 encoded string
  96. Function EncodeUTF8(s)
  97.   Dim i
  98.   Dim c
  99.  
  100.   i = 1
  101.   Do While i <= len(s)
  102.     c = asc(mid(s,i,1))
  103.     If c >= &H80 Then
  104.       s = left(s,i-1) + chr(&HC2 + ((c And &H40) / &H40)) + chr(c And &HBF) + mid(s,i+1)
  105.       i = i + 1
  106.     End If
  107.     i = i + 1
  108.   Loop
  109.   EncodeUTF8 = s
  110. End Function
  111. %>

Al llamar a esa función dentro de mi código se acabaron los problemas de codificación:

Código ASP:
Ver original
  1. ' Transformamos la localidad de UTF8 a iso-8859-1 si está codificada en UTF8
  2. ' ============ IMPORTANTE ============
  3. ' ************************************
  4. ' Hay que decodificarla así porque el string se recibe en UTF8 siendo de origen Windows 1252 y provoca caracteres raros
  5. ' como es UTF8 valid hay que decodificarlo para que se transforme en Windows 1252
  6. ' En caso de ser invalid es porque nos lo han enviado directamente en Windows 1252 (caso de IE8) que es lo que nos interesa, no lo tranformamos
  7. If IsValidUTF8(Request.QueryString("loc")) Then
  8.     localidad = decodeUTF8(Request.QueryString("loc"))
  9. Else
  10.     localidad = Request.QueryString("loc")
  11. End If

Un saludo y espero que le sirva a alguien.
  #3 (permalink)  
Antiguo 10/09/2011, 06:11
 
Fecha de Ingreso: febrero-2008
Ubicación: Sevilla
Mensajes: 91
Antigüedad: 16 años, 2 meses
Puntos: 15
Respuesta: Problemas de especificación de charset

No entiendo como aun hay gente que usa ISO en su charset, cuando UTF-8 vale para todo
  #4 (permalink)  
Antiguo 12/09/2011, 10:55
 
Fecha de Ingreso: febrero-2010
Mensajes: 22
Antigüedad: 14 años, 2 meses
Puntos: 0
Respuesta: Problemas de especificación de charset

Es simple, la base de datos está hecha así y está pensada para una aplicación de escritorio, donde "daba igual" uno que otro. El tema es que 5 años después se ha necesitado llevar esa base de datos a una web... y así pasa. Si hubiesen pensado directamente en web hubiesen usado UTF-8 pero como no es el caso y se adaptó mucho más tarde, pues... :P.

Etiquetas: ajax, charset, especificación, post, select
Atención: Estás leyendo un tema que no tiene actividad desde hace más de 6 MESES, te recomendamos abrir un Nuevo tema en lugar de responder al actual.
Respuesta




La zona horaria es GMT -6. Ahora son las 10:28.