出于对安全问题的考虑,Ajax应用中,浏览器默认是不支持跨域调用的。不过很幸运,从jQuery 1.2以后,就开始支持JSONP的调用,使ajax跨域获取数据变得更加容易。
这是昨晚加班的时候遇到一个问题,服务器A(域名aa.domian.com)上放置了所有游戏广告页和引导页,一般这样的页面是不需要连接数据库的,因此该服务器上并未配置数据库连接的环境。不过我的工作是在这里创建一个页面并且要显示游戏官方网站(处于域gg.domain.com)上的一些数据,仅仅是请求一个不长的字符串而已,我想到用ajax来解决,很快我就遇到了IE浏览器提示的javascript错误“没有权限”(oh!进行了跨域请求)。后来我使用jquery很快地把这跨域的数据追捕到了,听起来有点像是在为jq做广告。
使用示例:
var url = “http://www.###.com/test.php?name=a”;
jQuery.getJSON(url +”&jsoncallback=?”, function(data){
alert(”return msg:” + data.msg);
});
在服务端程序:
$visitor = $_GET['name'];
$callback = $_GET['jsoncallback'];
$msg = ‘hello ‘ . $_GET['name'] . ‘, this is server B!’;
//服务端返回
$json_data = ‘{”msg”:”‘ . $msg . ‘”}”;
echo $callback . ‘(’ . $json_data . ‘)’;
这样,在客户端得到的返回程序可能是:
JQUET0988788({”msg”:”hello a, this is server B!”})
总之,我们要做的是两件事:
1. 在请求地址里加上参数 jsoncallback=?
2. 在服务端程序里把jsoncallback的值和数据一起返回,形如 $callback . ‘(’ . $json_data . ‘)’
至此,问题解决了。
asp.net 示例:
客户端:
function submitData() {
//encodeURIComponent:防止中文乱码
var getUsername =encodeURIComponent((jQuery("#txtUserName").val()));
var getUserPassword = jQuery("#txtPwd").val();
var getCode= jQuery("#txtCode").val();
if (getUsername.replace(//s/ig, "").length < 2) { alert("用户名为空或填写有误"); return false; }
if (getUserPassword.replace(//s/ig, "").length < 2) { alert("密码为空或填写有误"); return false; }
var url=getid+"&txtUserName="+getUsername+"&txtPwd="+getUserPassword+"&txtCode="+getCode+"&jsoncallback=?";
if (getCode.replace(//s/ig, "").length != 4 || isNaN(getCode)) { alert("请检查验证码填写是否有误"); }
jQuery.getJSON("http://www.chinayq.com/download/File_Jquery.aspx?PageFlag=3&id=" + url,
function(data) {
if (data.err == "0") { alert(data.errmsg); return false; }
if (data.err == "1") { alert("登陆成功"); jQuery("#dizhi").html(data.errmsg); jQuery(".hezc").hide(); }
}); return false;
}
服务端:
/// <summary>
/// 验证登陆用户
/// HttpUtility.HtmlDecode 用于编译客户端js中文编译成的代码
/// </summary>
protected void ValitionUser()
{
string errmsg = "true";
string callBack=Request.Params["jsoncallback"];
string PageFlag = WebUtility.Comm.GetString("PageFlag");
if (PageFlag == "3")
{
string code =WebUtility.Comm.NoHTML(WebUtility.Comm.GetString("txtCode"));
string uname =HttpUtility.HtmlDecode(WebUtility.Comm.NoHTML(WebUtility.Comm.GetString("txtUserName", 20)));
string pwd = WebUtility.Comm.GetString("txtPwd", 20);
if (!string.IsNullOrEmpty(uname) && !string.IsNullOrEmpty(pwd))
{
DataTable dt = new BLL.News.User().GetList("UserName='" + uname + "'").Tables[0];
if (dt.Rows.Count > 0)
{
DataRow[] dr = dt.Select("PassWord='" + System.Web.Security.FormsAuthentication.HashPasswordForStoringInConfigFile(pwd, "md5") + "'");
if (dr.Length > 0)
{
int Id = int.Parse(dr[0]["Id"].ToString());
//记录cookies
new BLL.News.User().WriteCookies(Id);
//更新信息
new BLL.News.User().UpdateState(Id, "LastTime", "'" + DateTime.Now + "'");
new BLL.News.User().UpdateState(Id, "LogCount", "LogCount+1");
}
else
{
errmsg = "{/"errmsg/":/"用户名或密码不正确/",/"err/":/"0/"}";
}
}
else
{
errmsg = "{/"errmsg/":/"用户名或密码不正确/",/"err/":/"0/"}";
}
}
else
{ errmsg = "{/"errmsg/":/"用户名或密码不能为空/",/"err/":/"0/"}"; }
Response.ContentType = "application/json";
if (errmsg == "true" && ModuleID!=0) {
读取数据库语句:省略
if (dsaddress.Tables[0].Rows.Count > 0)
{
for (int i = 0; i < dsaddress.Tables[0].Rows.Count; i++)
xiaZaiDiZhi += "<a href='" + dsaddress.Tables[0].Rows[i][1].ToString() + "' target='_blank'>" + dsaddress.Tables[0].Rows[i][0].ToString() + "</a>";
}
Response.Write(callBack+"({/"errmsg/":/"" + xiaZaiDiZhi + "/",/"err/":/"1/"})"); Response.End();
}
else { Response.Write(callBack + "("+errmsg+")"); Response.End(); }
}
asp.net : 示例地址:http://down.chinayq.com/West/100921-1760.html