出于對安全問題的考慮,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