将JSON视为文本的浏览器

时间:2015-08-24 19:49:43

标签: php jquery ajax json symfony

我有一个带有一些Ajax调用的Symfony 2.7应用程序,它们大致相同:

    $.ajax({
        type: 'POST',
        url: some_url,
        data: object,
        dataType: 'json',
        success: function(data){
            if(data.success){
                console.log(data.success);
                //do stuff

            }               
        }
    })
    .fail(function(data){
        console.log('oops');
        console.log(data);
    })
    .always(function(){
        console.log('completed');
    });

除了一个调用之外的所有调用都会显示Request标头accepts = application/json, text/javascript, */*; q=0.01。其中一个电话有accepts = text/html, application/xhtml+xml, */*。每当进行该调用时,返回的JSON将显示为文本,而不是由ajax.success方法处理。

这是返回的JSON对象,但显示为文本:

{"success":true,
 "msg":"Your search was successfully saved.",
 "link":"\u003Ca  href=\u0022\/expertise\/web\/app_dev.php\/en\/search\/savedsearch\/15\u0022\u003Ebar\u003C\/a\u003E\u003Ca  class=\u0027actionlink delete\u0027 href=\u0022\/expertise\/web\/app_dev.php\/en\/search\/delsearch\u0022 data-query_id=15\u003E\u0026nbsp;\u003C\/a\u003E"
}

Jsonlint说它有效。

以下是使用Response标头content-type = application/json返回上述JSON对象的方法(来自我的Symfony控制器)。我的应用程序使用FOSJsRoutingBundle,JMSSecurityExtraBundle和JMSDiExtraBundle。

/**
 * @Route("/savesearch", name="exps_savesearch", options={"expose"=true})
 * @Secure(roles="ROLE_MGR, ROLE_SUP")
 * @Method("POST")
 * @return JsonResponse
 */
public function savesearchAction(Request $request){
    $ajaxinfo = new \stdClass();

    $adsearcher = $this->get('exp_adsearcher');
    $person = $adsearcher->getPersonByUserName($this->getUser()->getUsername());

    $search = new SavedSearch();
    $search->setPerson($person);

    $form = $this->createForm(new SaveSearchType,$search);
    $form->handleRequest($request);
    if($form->isValid()){
            $em = $this->getDoctrine()->getManager();
            $em->persist($search);
            $em->flush();

            $ajaxinfo->success = true;
            $ajaxinfo->msg=$this->get('translator')->trans('message.search.save.success');
            $ajaxinfo->link = $this->renderView('ExpertiseDefaultBundle:Search:searchlink.html.twig', array('id'=>$search->getId(), 'name'=>$search->getSearchName()));
    } else {
        $ajaxinfo->success = false;
        $ajaxinfo->msg= $this->renderView('ExpertiseDefaultBundle:Form:formerrors_ajax.html.twig',array('form'=>$form->createView()));
    }
    return new JsonResponse($ajaxinfo);
}

为什么accepts = text/html, application/xhtml+xml, */*时请求标头ajax.dataType: json?这就是为什么所有浏览器都将此JSON视为文本的原因?

ETA:

@Quentin和@Mike Brant关于提交ajax电话的表单提交的评论可能是正确的。这是包装ajax调用的代码:

$('form[name="savesearchform"]').on('submit', function(e){
    e.preventDefault();
    var frm = this;
    $('.error',$(frm)).remove();
    $('#delsearch_msg').empty();
    $('#savesearch_msg').empty();
    $.ajax({ /* as above */ }).fail(function(data){ /* as above */ }).always(function(){ /* as above */ });
});

我原以为e.preventDefault();会阻止默认操作。但也许不是。那么我该如何解决呢?

2 个答案:

答案 0 :(得分:1)

我知道这很奇怪因为JsonResponse必须返回正确的标题 但是怎么样?

$response = new Response();
$response->setContent(json_encode($ajaxinfo));
$response->headers->set('Content-Type', 'application/json');
return $response;

也在这里http://symfony.com/doc/current/components/http_foundation/introduction.html你可以看到使用JsonResponse的例子。也试试这个:

$response = new JsonResponse();
$response->setData(get_object_vars($ajaxinfo));
return $response;

如果问题仍然存在,我认为可能有某个替换标头的过滤器。必须调试。

答案 1 :(得分:0)

这令人尴尬。我在html中发现了一个拼写错误,这意味着表单名称不匹配,因此从未调用过javascript。

我感谢大家的帮助,并尽我所能。