2012-05-10 4 views
3

ПРИМЕЧАНИЕ: Я вставил больше кода, чем просто вызовы ajax, в том случае, если этот код является (частью) того, что вызывает проблему. Я не думаю, что это так, поэтому вам, вероятно, лучше сосредоточиться на функциях ajax и jAjax немного ниже.
Также обратите внимание, что, поскольку есть комментарий (с upvote) по этому вопросу, говорящий, что мой код трудно расшифровать, я бы с радостью прояснил, что нужно уточнить, если это может оказаться ключом к поиску проблемы.
Спасибо.


Вот что. Я пытаюсь вырезать jQuery, так как единственное, что я использую, - это метод $.ajax(), и в том числе целый lib, такой как jQuery только для 1 функции, является ИМО безумным. Мне вообще не нужна полная функциональность метода $.ajax, поэтому я написал свою собственную функцию ajax.

Проблема в том, что она не работает, и я не могу понять, почему. Я пытаюсь отправить объекты на сервер (в частности: ajaxAction в контроллере - с помощью Zend FW). Ниже приведен код javascript и краткое описание того, что мне сообщает консоль firebug.

if (!String.prototype.trim) 
{ 
    String.prototype.trim = function() 
    { 
     "use strict"; 
     return this.replace(/^\s\s*/, '').replace(/\s\s*$/, ''); 
    }; 
} 

function getUrl(action,controller) 
{ 
    var base,uri; 
    base = window.location.href.replace('http://'+window.location.host,''); 
    if (base.length > 1) 
    { 
     base = base.substring(1,base.length).split('/'); 
     controller = controller || base[0]; 
     base[0] = controller || base[0]; 
     base[1] = action || base[1]; 
     return '/'+base.join('/'); 
    } 
    controller = controller || 'index'; 
    action = action || 'ajax'; 
    return base+controller+'/'+action; 
} 

function formalizeObject(obj,recursion) 
{ 
    recursion = recursion || false; 
    if (typeof obj !== 'object') 
    { 
     throw new Error('no object provided'); 
    } 
    var ret = ''; 
    for (var i in obj) 
    { 
     if (!obj.hasOwnProperty(i) || typeof obj[i] === 'function') 
     { 
      continue; 
     } 
     if (recursion) 
     { 
      ret +='['+i+']'; 
     } 
     else 
     { 
      ret += (ret.length > 0 ? '&' : '') + i.toString(); 
     } 
     if (typeof obj[i] === 'object') 
     { 
      ret += formalizeObject(obj[i],true); 
      continue; 
     } 
     ret += '='+obj[i].toString(); 
    } 
    if (recursion) 
    { 
     return ret; 
    } 
    return encodeURI(ret); 
} 

function success() 
{ 
    if (this.readyState===4 && this.status===200) 
    { 
     console.log(this.responseText); 
    } 
} 

function ajax(str,url,method,json) 
{ 
    var ret; 
    json = json || false; 
    str = str || {}; 
    method = method || 'POST'; 
    url = url || getUrl(); 
    str = 
    str = (typeof str === 'object' ? str : {data:str}); 
    try 
    { 
     ret = new XMLHttpRequest(); 
    } 
    catch (error) 
    { 
     try 
     { 
      ret= new ActiveXObject('Msxml2.XMLHTTP'); 
     } 
     catch(error) 
     { 
      try 
      { 
       ret= new ActiveXObject('Microsoft.XMLHTTP'); 
      } 
      catch(error) 
      { 
       throw new Error('no Ajax support?'); 
      } 
     } 
    } 
    if (typeof ret !== 'object') 
    { 
     throw new Error('No Ajax, FFS'); 
    } 
    ret.open(method, url, true); 
    ret.setRequestHeader('X-Requested-With', 'XMLHttpRequest'); 
    ret.setRequestHeader('Content-type', (json ? 'application/json' : 'application/x-www-form-urlencode')); 
    ret.onreadystatechange = success; 
    ret.send((json ? JSON.stringify(str) : formalizeObject(str))); 
    return true; 
} 

function jAjax(str,url) 
{ 
    $.ajax(
    { 
     url : url, 
     data: str, 
     type: 'POST', 
     success: function(res) 
     { 
      console.log(res); 
     } 
    }); 
} 

Четыре способа, в котором я пытался сделать запрос Ajax:

jAjax({data:{foo:'bar'}},getUrl());//1 
jAjax({data:{foo:'bar'}},getUrl(),true);//2 
ajax({data:{foo:'bar'}},getUrl());//3 
ajax({data:{foo:'bar'}},getUrl(),true);//4 
  1. jAjax({data:{foo:'bar'}},getUrl());: Это работает просто отлично:

    [] { "Аякса" : true, «controller»: «index», «action»: «ajax», «module»: «default», «identity»: {}, «data»: {"foo": "Bar"}} Параметры : data [foo] 'bar' И Источник: данные% 5Bfoo% 5D = Ba r (из вкладки POST в консоли FB) Заголовок: application/x-www-form-urlencoded; кодировка = UTF-8
    Все это было отправлено по следующему адресу: http://www.foo.bar/index/ajax?data%5Bfoo%5D=bar

  2. Это не работает, однако:

    [] { "Ajax": истинные "контроллер ":" index "," action ":" ajax "," module ":" default "," identity ": {}} - ответ Вкладка POST в FB: данные JSON: {foo: 'Bar'} источник: {"data": {"Foo": "Bar"}} (но тот же url - случай 1) Заголовок: json; кодировка = UTF-8

  3. Это большой один: полный URL запроса совпадает с URL-адрес из корпуса 1, как и заголовки, НО когда я смотрю на вкладке POST в консоли FB (проверить запрос) Это единственное различие, которое я могу найти:

    случай 1: Параметры: данные [Foo] «бар» Источник: данные% 5Bfoo% 5D = бар
    В этом случае, я могу» см. раздел «Параметры»: только: Источник: данные% 5Bfoo% 5D = Бар

  4. Идентично к случаю2, за исключением URL-адреса, который, я думаю, забыл пройти через encodeURI. Этот случай сейчас менее важен. Я думаю/надеюсь, что я получу эту работу, когда выясню, что случилось с случаем 3.

Во всех четырех случаях запрос отправляется и принимается. Действия контроллера заключается в следующем:

public function ajaxAction() 
{ 
    $this->_helper->layout->disableLayout(); 
    $this->getHelper('viewRenderer')->setNoRender(); 
    $this->_helper->getHelper('AjaxContext')->addActionContext('ajax' , 'json') 
              ->initContext('json'); 
    if($this->getRequest()->isPost() && $this->getRequest()->isXmlHttpRequest()) 
    { 
     echo json_encode(array_merge(array('ajax'=>true),$this->_getAllParams())); 
    } 
    else 
    { 
     throw new Exception('no ajax call made??'); 
    } 
} 

Поскольку я получаю строку JSON, я уверен, что запрос размещен, и имеет правильный XMLHttpRequest заголовок. Почему же я не могу публиковать объекты JSON? Еще более важно: почему случай 3 не работает? Что такое jQuery, о котором я не знаю? Что это, что делает случай 1 работать, но не случай 3?

PS: Это может быть неуместным, но в момент безумия я попытался добавить это: ret.setRequestHeader('Connection','close'); функции ajax, но я заметил, что в заголовке, который был разослан, Connection был установлен, чтобы держать-живо все одна и та же. Возможно, это дает кому-то подсказку о том, что пошло не так?

Заранее спасибо

+2

Ваши мясистые части вашего сообщения трудно расшифровать, отчасти из-за размера и шума. Ну, для меня, по крайней мере. – goat

+0

Вы можете проверить [zepto.js] (http://zeptojs.com/), это попытка быть легкой альтернативой jquery, и вы можете проверить их функцию ajax. – Zombaya

+0

@chris: true, мне не следовало бы размещать весь код, там есть шанс, что там где-то есть проблема (хотя я думаю, что нет). Функции «ajax» и «jAjax» - это те, на которых нужно сосредоточиться. @ Zombaya: Я изучу его, хотя я на самом деле пытаюсь избавиться от фреймворка, поэтому я не хочу заменять его другим ... но кто знает, это может быть только то, что мне нужно –

ответ

1

В случае кто-нибудь спрашивает, что случилось:

ret.setRequestHeader('Content-type', 'application/x-www-form-urlencode'); 

Должно быть "х-WWW-форм-urlencoded", с "г" в конце:

ret.setRequestHeader('Content-type', 'application/x-www-form-urlencoded'); 

отправки объекта формализованное теперь работает, и я могу избавиться от JQuery :-)