2011-02-25 12 views
16

Encontré un montón de preguntas similares aquí, pero después de 3 horas de leerlas y probar cosas, estoy publicando las mías. Me disculpo por la duplicación, pero simplemente no sé lo que está pasando aquí.jQuery publicación causa Untaught SyntaxError: Token inesperado:

Así que tienen esta función javascript:

function saveSetting(settingName, settingValue) { 
    $.post(
     appUrl + "Account/SaveSetting", 
     { settingName: settingName, settingValue: settingValue }, 
     function (data) { 
      alert(data.Result); 
     }, 
     "json" 
    ); 
} 

que llamo así:

saveSetting("bookFontSize", fontSize); 

donde fontSize es "10.5" o algo similar.

Chrome informa de las cabeceras de la publicación así:

Request URL:http://localhost:1227/Account/SaveSetting?callback=jQuery151022712289774790406_1298625531801 
Request Method:POST 
Status Code:200 OK 
Request Headers 
Accept:text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01 
Accept-Charset:ISO-8859-1,utf-8;q=0.7,*;q=0.3 
Accept-Encoding:gzip,deflate,sdch 
Accept-Language:en-US,en;q=0.8 
Connection:keep-alive 
Content-Length:42 
Content-Type:application/x-www-form-urlencoded 
Cookie:ASP.NET_SessionId=jwpzp4okerckuh2bhkl2pnwu; .ASPXAUTH=429EEA1CFBFD9D5702011C59F77F18F8DAEEEB412314D608E86289779DF8ED9C80C6E0370B7108D68C44B088C7CB6998F34C59DDCFF8EA9D4A556495F5D40DF21737392DCF5942F73726882BEC354C35599864F751751FD458473FA4541AF25294F7E16DC00AABD4DEC43B321B0ECCBF195FD419C3BC912017275FC478A27F0C12A28D124A663EA5F19E5AEFFB276603 
Host:localhost:1227 
Origin:http://localhost:1227 
Referer:http://localhost:1227/Read/116/1 
User-Agent:Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US) AppleWebKit/534.13 (KHTML, like Gecko) Chrome/9.0.597.98 Safari/534.13 
X-Requested-With:XMLHttpRequest 
Query String Parameters 
callback:jQuery151022712289774790406_1298625531801 
Form Data 
settingName:bookFontSize 
settingValue:10.5 
Response Headers 
Cache-Control:private, s-maxage=0 
Connection:Close 
Content-Length:38 
Content-Type:application/json; charset=utf-8 
Date:Fri, 25 Feb 2011 09:18:53 GMT 
Server:ASP.NET Development Server/10.0.0.0 
X-AspNet-Version:4.0.30319 
X-AspNetMvc-Version:3.0 

que va a un C#/ASP.NET MVC3 acción que tiene este aspecto:

[Authorize] 
public JsonResult SaveSetting(string settingName, string settingValue) 
{ 
    try 
    { 
     repository.SaveSettingForUser(CurrentUser, settingName, settingValue); 
    } 
    catch (Exception ex) 
    { 
     return Json(new { Result = CurrentUser.IsAdmin() ? "Failed :" + ex.Message : "Failed" }); 
    } 
    return Json(new { Result = string.Format("Set {0} to {1}.", settingName, settingValue) }); 
} 

que, según cromo, vuelve este :

{"Result":"Set bookFontSize to 10.5."} 

que me parece legítimo json. Sin embargo, me sale este error en cromo:

Uncaught SyntaxError: Unexpected token : 

y éste en el IE 7 y 8:

An error has occurred in the script on this page. 
Line: 67456553 
Char: 10 
Error: Expected ';' 
Code: 0 
URL: http://localhost:1227/Read/116/1 

que definitivamente no tienen 67 millones de líneas de código :)

todos modos , ¿alguien sabe qué diablos está pasando aquí? Mi alerta no se ejecuta IE nunca obtiene la solicitud, pero Chrome sí.

Creo que esta función realmente funcionó con una versión anterior de jQuery hace mucho tiempo, con la configuración $.ajaxSettings.traditional = true, pero ahora no funciona (jQuery 1.5.1) con o sin esa configuración.

Actualización: Lo tengo trabajando. Pasé por el javascript con el depurador. Por alguna razón, durante el llamado .ajax() en jQuery, estaba entrando en jquery.validate.js. ¿Porqué haría eso? Tenía el archivo incluido, pero no lo estaba usando en ninguna parte. Eliminé el error simplemente al no hacer referencia a jquery.validate.js. Pero esto es una mierda, porque ¿qué pasa si quiero usar las funciones de validación en el futuro?

Así que mi pregunta ahora es "¿Por qué tener jquery.validate.js en mi proyecto arruina todo?"

Actualización 2: Hay un error en jquery.validate.js, que ahora se ha fijado en un tenedor de ese proyecto en GitHub. Ver mi respuesta para más detalles. Ni siquiera estaba usando las características de validación de ese archivo, simplemente incluyéndolo en la página para su uso posterior. Se pone en el camino y rompe las cosas. Nota del autor de jquery.validate.js con respecto a la corrección: "Corrige jQuery 1.5-code usando jQuery.ajaxSettings y no window.ajaxSettings (sí, eso fue tonto)".

Respuesta

21

¡Lo descubrí!

Es un error en jquery.validate.js. Se repite y documenta aquí: http://bugs.jquery.com/ticket/8064

El autor ha resuelto el problema el 2 de febrero de 2011, pero esta solución aún no se ha convertido en una versión oficial del complemento (desde el 25 de febrero de 2011 y jQuery Validate 1.7) . Si desea que jQuery 1.5+ JSON funcione mientras utiliza la validación de jquery, debe descargar el complemento de validación parcheado.

https://github.com/jaubourg/jquery-validation/raw/master/jquery.validate.js https://github.com/jaubourg/jquery-validation/raw/master/jquery.validate.min.js

Si usted está aquí de Google y los enlaces de arriba ya no funcionan, la actualización a una versión de validar que es mayor que 1,7, probablemente va a funcionar. Alternativamente, vaya aquí https://github.com/jaubourg/jquery-validation y obtenga la última versión del repositorio.

2011-08-31 Actualización: Parece que ya no usan ese enlace de GitHub. I think this is what you need.

+3

Awesome find. Me salvaste varias horas. – CreativeNotice

1

Declaraste la publicación como json, por lo que el resultado debe evaluarse automáticamente.

Sin embargo, tratar de evaluar el resultado antes de la alerta en el interior de los soportes de la alerta

eval(data.Result) 
+0

Por desgracia, eso no cambia nada. – Chris

0

Podría ser que los nombres clave de objeto se están creando dinámicamente en algunos navegadores? Intente cambiar SaveSetting a lo siguiente:

function saveSetting(settingName, settingValue) { 
    $.post(
     appUrl + "Account/SaveSetting", 
     { "settingName": settingName, "settingValue": settingValue }, 
     function (data) { 
      alert(data.Result); 
     }, 
     "json" 
    ); 
} 

O tal vez cambiar el nombre de argumento a algo más que el nombre clave de objeto:

function saveSetting(settingNameArg, settingValueArg) { 
    $.post(
     appUrl + "Account/SaveSetting", 
     { settingName: settingNameArg, settingValue: settingValueArg }, 
     function (data) { 
      alert(data.Result); 
     }, 
     "json" 
    ); 
} 
+0

¡Estos fueron fáciles de probar, así que fui por el tuyo primero! Desafortunadamente, ninguno ayudó. Además, probé ambos simultáneamente :) – Chris

0

va a devolver JSON incorrecta del servidor. Su JSON devuelto tiene un cierto carácter de control en el Result. Recomendaría enviar una cadena sin new String.format

+0

¿Cómo se puede saber esto? ¿Podría ser que este char solo sea el resultado de cortar y pegar las herramientas de cromo? – Chris

0

Nunca código urls. Siempre use helpers de url cuando maneje urls. Asimismo, no se proporcionan las direcciones URL absolutas como jQuery piensa que es JSONP (nótese el parámetro callback=jQuery151022712289774790406_1298625531801 en su solicitud), mientras que la respuesta sólo es JSON:

function saveSetting(settingNameArg, settingValueArg) { 
    $.post(
     '<%= Url.Action("SaveSetting", "Account") %>', 
     { settingName: settingNameArg, settingValue: settingValueArg }, 
     function (data) { 
      alert(data.Result); 
     }, 
     'json' 
    ); 
} 

Observe también que sus argumentos de la función son llamados settingNameArg y settingValueArg mientras que inyour código Estabas usando settingName y settingValue.

+0

Los argumentos de mi función no se llaman 'settingNameArg' y' settingValueArg'. ¿Estás diciendo que deberían estarlo? Usar esos nombres no hace diferencia. Esta función se encuentra en un archivo JS externo, por lo que el código del lado del servidor no está disponible.Pero la variable appUrl se configura de manera similar en un archivo diferente que sí es procesado por MVC. ¿Debo asegurarme de que omite el protocolo, el esquema y el nombre de host? – Chris

+0

Creo que puede estar en algo con la sugerencia de JSONP. ¿Qué hace que jQuery piense que necesita agregar ese parámetro de devolución de llamada? ¿Cómo debería ser ese parámetro de url? Lo intenté como/Account/SaveSetting y ../Account/SaveSetting y cada uno da como resultado el parámetro de devolución de llamada. – Chris

0

estoy usando esto:

// The Actionresult is being called by an Ajax Call: 
    public ActionResult SomePartial(Object model) 
    { 
    return Json(new { state="Success", date="some data" }); 
    } 

//OnSuccess of the Ajax Call: 
    function OnSuccess(ajaxContext) { 
    var result = eval(ajaxContext); 
    if (result.state == "Success") { 
    console.log(result.data) 
    } 
      else { 
       // ERRORS 
      } 

     } 

esto devuelve un objeto JSON válida y lo muestra :)

también NB para validar su JSON http://jsonlint.com/

Cuestiones relacionadas