【发布时间】:2012-05-19 01:14:17
【问题描述】:
注意:我粘贴了更多的代码,而不仅仅是 ajax 调用,因为代码是(部分)导致问题的原因。但是,我不认为是这样,因此您最好将注意力集中在ajax 和jAjax 函数上。
另外请注意,由于对此问题有评论(带有赞成票)说我的代码很难破译,我很乐意澄清需要澄清的内容,如果这可以证明是找到问题的关键。
谢谢。
事情就是这样。我正在尝试抛弃 jQuery,因为我唯一使用的是 $.ajax() 方法,并且包含一个像 jQuery 这样的整个库仅用于 1 个功能是 IMO 疯狂的。我什至不需要$.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
-
jAjax({data:{foo:'bar'}},getUrl());:这很好用:[]{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{},"data":{"foo “:“酒吧”}} 参数:data[foo] 'bar' 来源:data%5Bfoo%5D=Bar(来自 FB 控制台中的 POST 选项卡) 头文件:application/x-www-form-urlencoded;字符集=UTF-8
所有这些都发送到以下网址:http://www.foo.bar/index/ajax?data%5Bfoo%5D=bar -
但是这不起作用:
[]{"ajax":true,"controller":"index","action":"ajax","module":"default","identity":{}} 是响应 FB 中的 POST 选项卡:JSON 数据:{foo:'Bar'} 来源:{"data":{"Foo":"Bar"}}(但相同的 url 是 case 1) 头文件:json; charset=UTF-8
-
这是最重要的:完整的请求 url 与案例 1 中的 url 相同,但当我查看 FB 中的 POST 选项卡时,标题也是如此控制台(检查请求)这是我能找到的唯一区别:
案例1:参数:data[foo] 'bar' 来源:data%5Bfoo%5D=Bar
在这种情况下,我看不到“参数”部分,只有:来源:data%5Bfoo%5D=Bar 与 case2 相同,除了 url,我想我忘记通过
encodeURI。这个案子现在不那么重要了。我想/希望在我弄清楚案例 3 有什么问题的那一刻,我就能解决这个问题。
在所有 4 种情况下,请求都被发送和接收。控制器动作如下:
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 设置为保持活力都一样。也许这可以让某人知道出了什么问题?
提前致谢
【问题讨论】:
-
您帖子中的大量内容难以解读,部分原因是尺寸和噪音。好吧,至少对我来说。
-
你可以查看zepto.js,它试图成为 jquery 的轻量级替代品,你可以查看他们的 ajax 函数。
-
@chris: 是的,我不应该把所有的代码都贴出来,如果某个地方有问题(虽然我不这么认为),它就在那里。
ajax和jAjax函数是需要关注的。 @Zombaya:我会调查它,虽然我实际上是在尝试摆脱一个框架,所以我不热衷于用另一个框架来替换它......但谁知道呢,它可能正是我所需要的跨度> -
你可以保留你的 jquery 库,即使是 1 个函数。通过适当的缓存控制和根据请求对文件进行 gzip 压缩,跟踪变得最小,因为客户端只会下载一次并将其缓存在浏览器临时文件中
-
@JFDion:我想避免的不仅仅是 jQuery 库的绝对大小。 jQuery 很棒,这是毫无疑问的,但是它很慢。基本上,您要说的是:您可以不问这个问题并保持原样,并在不知道为什么的情况下接受它的工作原理。
标签: php javascript ajax json zend-framework