未捕获的SyntaxError:意外的令牌:在JSON响应中

时间:2013-11-27 12:54:10

标签: json syntax-error token

此代码试图实现的目标:

我想创建一个小部件,它将生成一个客户最新X评论的容器。这个小部件可以放在我客户的任何网站上,所以不能放在我自己的网站上。 因此,我认为我需要使用JSONP来支持跨域调用。

调用我的webservice时出现意外的令牌错误? JSON似乎是正确的。 我的回调函数现在永远不会被击中。

Test.aspx文件

<script type="text/javascript" src="http://www.testsite.com/script/widget/myReviews.js"></script>

<div id="ww-widget-reviews" class="ww-reset ww-reviews-widget"></div>

<script type="text/javascript">
    testsite.createReview({ "vendorId": "315", "type": "1", "id": "ww-widget-reviews" });
</script>

myReviews.js中的相关功能

testsite.createReview = function(c) {
    testsite.reviewWidgetId = c.id;
    console.log('calling service');
    var a = "http://www.testsite.com/testservice.svc/getcompanyreviewdetails/?id=" + c.vendorId + "&t=" + c.type + "&callback=testsite.writeReviewsCallback";
};

testsite.writeReviewsCallback = function (b) {
    alert('hi in the callback'); //this line is never hit
    var a = document.getElementById(testsite.reviewWidgetId);
    a.className = "ww-reset ww-reviews-widget";
    a.innerHTML = testsite.getReviewWidget(b);
};

Itestservice.vb

<OperationContract()> _
<Web.WebInvoke(Method:="GET", ResponseFormat:=Web.WebMessageFormat.Json, BodyStyle:=Web.WebMessageBodyStyle.Bare, _
UriTemplate:="getcompanyreviewdetails/?id={id}&t={t}")> _
        Function getCompanyReviewDetails(ByVal id As Integer, ByVal t As Integer) As Stream

服务的响应是:

{
    "responseHeader": {
        "status": 0,
        "QTime": 0,
        "params": {
            "facet": "false",
            "fl": "id,title,friendlyurl,reviewnickname,reviewtext,overallscore,objecttype,rating,rating_total",
            "indent": "off",
            "q": "*:*",
            "wt": "json",
            "fq": "id:315"
        }
    },
    "response": {
        "numFound": 1,
        "start": 0,
        "docs": [
            {
                "friendlyurl": "beachclub-sunrise",
                "id": "315",
                "title": "Beachclub Sunrise",
                "rating": 8.25,
                "rating_total": 8,
                "reviewnickname": [
                    "Van Voorenberghe",
                    "Echtpaar",
                    "Spijker",
                    "Kim Kok",
                    "TOP feest",
                    "Carolien en Remco",
                    "Roel en Ilja",
                    "Sanne poell"
                ],
                "reviewtext": [
                    "Wij zijn getrouwd in zaal Bruisend. Een ontzettend mooie witte zaal vol karakteristieke elementen. De prijs was goed en de bediening nog beter. Een echte aanrader! Uitkijk op het water, een terras voor de rokers onder ons en echt sfeervol ingericht.",
                    "Wij hebben een slechte ervaring met de mensen van de Beachclub.\r\nOnze ceremonie vond plaats op het ponton, gevolgd door een buffet en een feest. \r\nEchter de service was erg slecht. We hadden van te voren afspraken gemaakt, maar daar werd op de dag zelf geen aandacht aan geschonken. \r\nHet is voor ons een bijzondere dag en voor ons en vele gasten zou het een leuke dag moeten zijn. We betalen daar veel geld voor, maar dat heeft voor hen geen waarde. \r\nZe hebben wel excuses aangeboden maar we hebben geen tegemoetkoming in het geld gehad. We hebben dus betaald voor dingen die we niet gekregen hebben. Na afloop bleek het dat zaken duurder waren dan van te voren werd gesuggereerd.",
                    "Afgelopen augustus zijn wij hier getrouwd. We hadden van tevoren een aantal prettige, vriendelijke gesprekken waarin besproken werd welke zaal, welke consumpties, etc. Er was op een gegeven moment wat miscommunicatie (over welke zaal we gereserveerd hadden) maar dit kon gelukkig nog worden opgelost. Het gekozen diner kon van tevoren worden geproefd.\nOp de dag zelf arriveerden wij laat en liep het diner dus uit, dit is in overleg tussen de keuken/bediening en onze ceremoniemeesters flexibel en zonder problemen verlopen. Het eten heeft een prima prijs-kwaliteit verhouding, hoewel de details van de gerechten verschilden bij het proefeten en het diner op de bruiloft zelf. Vooral de tournedos viel in de smaak :) Het diner hielden we in Bruisend, het mooie openbare restaurant van de locatie. Onze bruiloft viel net buiten het hoogseizoen en ondanks het prachtige weer hebben we geen andere gasten dan onze bruiloftsgasten gezien.\nDe bediening is erg vriendelijk en de sfeer van de feestzaal, Sunset, paste helemaal bij hoe we onze bruiloft wilden: knus, vrolijk, gezellig, zomers. Sunset is exotisch ingericht en vanuit de zaal kun je het terras en eventueel verder het strand oplopen. Voor ons een mooie afsluiter van de dag, we kijken met een tevreden gevoel terug!",
                    "Eind September 2012 hebben wij onze bruiloft gevierd in beachclub Sunrise, zaal Sunset.  We hebben romantische foto's gemaakt op het strand en in het water... een aanrader! Samen met onze daggasten een bijzondere middag gehad en genoten van een heerlijk diner. Service was uitstekend. De avond werd afgesloten met een knalfeest! Na grote twijfels tussen het boeken van een band of dj... hebben we via Aqua Best, dj Harry en saxofonist geboekt, succes gegarandeerd! Vanaf het begin stond de dansvloer helemaal gevuld en er is volop gedanst tot het einde. Nog steeds krijgen we veel complimenten over het personeel en de verzorging van het feest. Het was allemaal top geregeld.  De locatie is romantisch, knus en heel sfeervol. Helemaal zoals wij het wilde! Een bijzondere, unieke plek voor een onvergetelijke dag!",
                    "In september 2010 zijn wij getrouwd en we hebben geborreld, gegeten en gefeest bij Bruisend. Ook hebben we op de pier nog foto's gemaakt. Het was een geweldige dag. Super goede service en eten en drinken in overvloed. Perfect verzorgd allemaal en een SUPER sfeertje. Van te voren hebben we duidelijk onze wensen besproken en bijna alles was mogelijk. Er wordt door ons en onze vrienden/ familie nog geregeld gesproken over dit fantastische feest. Zeker een aanrader dus!",
                    "wij zijn op 1 juni 2012 getrouwd op Sunrise en hebben er aansluitend gegeten en gefeest. Trouwen deden we op het Ponton, en dat had een heel romantisch sfeertje. daarna hebben we lekker genoten van de BBQ en als klapper een mega groot feest, niemand heeft gezeten iedereen danste!Helemaal geweldig was dat we zelfs op het terras een springkussen mochten plaatsen voor de kids die er overdag waren! we hebben alleen maar leuke en fantastische reacties gehad van vrienden en familie. ze hebben onze dag helemaal tot een om nooit meer te vergeten gemaakt en we hebben samen met ons zoontje echt genoten! beter kan een huwelijk niet beginnen!",
                    "Sunrise was in een woord FANTASTISCH! Namens ons, maar ook namens alle gasten. Al vanaf het eerste informerende gesprek werd de tijd voor ons genomen, luisterend naar waar we op zoek zijn en bespreken wat er mogelijk is. Vrijblijvend, vriendelijk en relaxt. \nDe dag zelf was ook goed. De bediening was zeer vriendelijk, snel, attent en de hele dag goed aanwezig. Diner was lekker.\nHet waren vooral de finishing details die ons speciaal deden voelen: pro-actief vragen of we wat extra frietjes willen voor onze peuter, altijd een vriendelijke glimlach en interesse voor de gasten, de barman die niet moeilijk doet als een van de daggasten een whisky wil drinken ipv. een mix-drank, prive-bediening voor het bruidspaar: er werd goed op ons gelet, en we hebben de hele dag niet een keer om bediening hoeven vragen.\nWat we erg fijn vonden was de balans van de dag: ‘s middag rustig en relaxt, en ‘s avonds party. Uiteraard ook mogelijk omdat Sunrise verschillende locaties/ zalen heeft, en mooie lounge faciliteiten.\nHet feest was ook super. DJ Harrie was de koning! We hadden een vrij complex gezelschap met alle leeftijdsgroepen aanwezig, maar hij heeft de dansvloer vol gekregen en gehouden tot het einde. Bediening, versiering, verlichting: alles prima!\nWe hebben heel veel positieve feedback ontvangen en ik weet zeker dat Sunrise er weer nieuwe toekomstige klanten bij heeft.\n",
                    "Wij zijn 14-09-2012 getrouwd op het ponton van sunrise, absoluut een unieke en bijzondere locatie. Wij zijn verder heel de dag op sunrise gebleven dus ook het diner en feestavond daar gehad. En onze trouwdag was meer dan geslaagd. De begeleiding van sunrise met tips en ideeën was super. De service met betrekking tot hapjes en drankjes was super, niemand stond zonder drinken. De huis dj was top, en we hadden een top feest met iedereen op de dansvloer! Kortom ik raad iedereen aan om bij sunrise te trouwen!!"
                ],
                "overallscore": [
                    10,
                    1,
                    8,
                    9,
                    9,
                    10,
                    9,
                    10
                ]
            }
        ]
    }
}

更新:将JSON包装在回调函数中

基于我现在的评论:

testsite.createReview = function(c) {
    testsite.reviewWidgetId = c.id;
    console.log('calling service');
    var a = "http://www.testsite.com/testservice.svc/getcompanyreviewdetails/?id=" + c.vendorId + "&t=" + c.type + "&callback=parseWeddingJSON"; 
    var b = document.createElement("script");
    b.setAttribute("type", "text/javascript");
    b.setAttribute("src", a);
    testsite.headLoc.appendChild(b);
};

function parseWeddingJSON(json) {
    console.log('parseWeddingJSON');
    console.log(json);
};

parseWeddingJSON函数未执行。我是否需要在服务配置中以某种方式支持此callback参数?因为现在我只定义了2个参数id' and t`。

3 个答案:

答案 0 :(得分:2)

在你的代码中你有这个:

var a = "http://www.wonderweddings.com/weddingservice.svc/getcompanyreviewdetails/?id=" +   c.vendorId + "&t=" + c.type;//+ "&callback=WonderWeddings.writeReviewsCallback";

var b = document.createElement("script");
b.setAttribute("type", "text/javascript");
b.setAttribute("src", a);
WonderWeddings.headLoc.appendChild(b);

但此网址的输出为JSON,而非javascript。 要解决它,只需替换

b.setAttribute("type", "text/javascript");

b.setAttribute("type", "application/json");

错误已经解决。

无论其

您无法访问脚本源的内容。通常,您应该进行ajax调用,以便从网址获取json。

如果要使用脚本标记(因为跨域策略),则应返回有效的javascript语法。

类似的东西:

callback({"yourjson":"here"})

以及代码中的其他位置,您必须定义回调:

function callback(json) {
     console.log(json);
}

这一切都是一项名为JSONP的技术。

该技术期望通过解析JSON的javascript声明一个函数:

function parseWeddingJSON(json) {
     console.log(json);
     // ... parse json here
};

附加一个脚本标签,通过获取之前声明的函数的名称:

var src = "http://www.wonderweddings.com/weddingservice.svc/"+
"getcompanyreviewdetails/?id=" +   c.vendorId + "&t=" + c.type+
"&callback=parseWeddingJSON"; // <--- see here
// create script with src as source.

服务器生成的输出将是这样的:

 parseWeddingJSON({"json":"here"});

(你必须通过VB手动完成)。 这是一个有效的javascript,只需调用解析JSON数据的函数。

答案 1 :(得分:1)

好消息,您的Feed是100%有效的JSON!您只需要完成JSONP的设置即可。你几乎做得对;你只需要你的服务器用回调函数包装你的对象(因此,对于代码中当前的请求[包括回调],服务器响应将是:

WonderWeddings.writeReviewsCallback({"responseHeader":{...}});

由于您的Feed被注入<script>标记,因此您的服务器需要将其准备好像是一个.js文件,而不是只返回一些JSON。

现在,您的字符串正在作为 JavaScript代码执行,而不是被解释为 JavaScript对象!这是

之间的区别
{
  var d = 2;
}

{
  "response":{}
}

在这两种情况下,你都可以看到我正在使用{}标签,但是第一个是有效的JS(和无效的JSON),第二个是无效的JS,因此你的SyntaxError:行"response":{}在JS中没有任何意义!完成JSONP将解决这部分问题,因为您的对象将位于callback()方法内部,并将被解释为对象,就像您想要的那样。

<强>加了:

是的,就像您在更新中所想的那样,您的服务器需要更新以支持回调参数;除非你使用某些框架,否则你不会免费获得它。

服务器需要检查回调参数是否存在,如果存在,它返回的最终结果应该是

<callbackParam>( {"responseHeader":{...}} );

使用JSONP,您的服务器结果实际上应该是可以运行的有效JavaScript文件。这是服务器生成的脚本,它将启动你的回调方法。

在大多数情况下,这很简单,只需将回调参数回显到结果中,然后在JSON对象周围回显()

答案 2 :(得分:0)

如果您查看reviewtext,我会看到这个......

  

verlichting:alles prima!

我怀疑那里的冒号打破了解析。尝试将其作为测试。

如果这不是问题,那么我认为您需要为JSONP实现此功能。这表明您使用了回调函数,就像您所做的那样......

  

包含回调函数名称的URI的查询参数   被指定为行为

的CallBack属性

请点击此处了解如何使用WCF, JSONP and Jquery