JavaScript出于安全方面的考虑,不允许跨域调用其他页面的对象。但在安全限制的同时也给注入iframe或是ajax应用上带来了不少麻烦。这里把涉及到跨域的一些问题简单地整理一下:
首先什么是跨域,简单地理解就是因为JavaScript同源策略的限制,a.com 域名下的js无法操作b.com或是c.a.com域名下的对象。更详细的说明可以看下表:
URL | 说明 | 是否允许通信 |
http://www.a.com/a.js | 同一域名下 | 允许 |
http://www.a.com/lab/a.js | 同一域名下不同文件夹 | 允许 |
http://www.a.com:8000/a.js | 同一域名,不同端口 | 不允许 |
http://www.a.com/a.js | 同一域名,不同协议 | 不允许 |
http://www.a.com/a.js | 域名和域名对应ip | 不允许 |
http://www.a.com/a.js | 主域相同,子域不同 | 不允许 |
http://www.a.com/a.js | 同一域名,不同二级域名(同上) | 不允许(cookie这种情况下也不允许访问) |
http://www.cnblogs.com/a.js | 不同域名 | 不允许 |
特别注意两点:
第一,如果是协议和端口造成的跨域问题“前台”是无能为力的,
第二:在跨域问题上,域仅仅是通过“URL的首部”来识别而不会去尝试判断相同的ip地址对应着两个域或两个域是否在同一个ip上。
“URL的首部”指window.location.protocol+window.location.host,也可以理解为“Domains, protocols and portsmust match”。
以上借鉴http://www.cnblogs.com/rainman/archive/2011/02/20/1959325.html的内容。
Javascript用soap方式 访问webservice并且调用webservice的函数,再得到返回的结果是可以的,这种方式应该主要是解析xml,这个方式我试了一下,一是麻烦,二是在IEok的情况下,谷歌浏览器却不可以,其中问题我还不清楚。
jQuery ajax访问webservice在跨域下请求返回json,xml,html,scaipt,text的格式数据会报错。
Error :XMLHttpRequest cannot load “XXX” Origin null is notallowed by Access-Control-Allow-Origin.
jQuery ajax访问webservice在不跨域下请求返回json,xml,html,scaipt,text的格式数据是可以的。
jquery ajax跨域下请求jsonp格式是ok的。
下面是一个跨域实例:
Webservice端:
using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using Newtonsoft.Json;
using System.Data;
using System.Web.Script.Services;//这个好像也不需要
using System.Runtime.Serialization;
namespace WebService2
{
///<summary>
/// Summary description for Service1
///</summary>
[WebService(Namespace= "http://tempuri.org/")]
[WebServiceBinding(ConformsTo= WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
//[System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
publicService1()
{
}
[WebMethod]
//[ScriptMethod(ResponseFormat= ResponseFormat.Json)]
public void getJson()
{
//这是jsonp数据格式,跨域情况下只能用jsonp格式,其他方法解决跨域问题不了解。
Context.Response.Write("getJson({'id':'0','name':'','message':'0','ipoint':'0','gpoint':'0'})");
Context.Response.End();
}
[WebMethod]
//[ScriptMethod(UseHttpGet= true)]
public string getText()
{
//下面是json的格式,jquery ajax在不跨域的情况下可以指定返回格式,可以是xml,json,html,script,text
return"{'user':{'id':'0','name':'','message':'0','ipoint':'0','gpoint':'0'}}";
}
}
}
JS端:
<!DOCTYPE html>
<html>
<head>
<scriptsrc="js/jquery-1.11.2.min.js"></script>
<scripttype="text/javascript">
$.noConflict();
jQuery(document).ready(function(){
jQuery("#p1").click(function(){
jQuery(this).hide();
});
jQuery("#p2").click(function () {
var url= "http://localhost:14023/Service1.asmx/getJson";
jQuery.ajax(url,{
type:"GET", //你选择get或者post最后都是get,跨域情况下都是get
contentType: "application/json", //不确定什么用
data: "{}", //这里是要传递的参数,格式为data: "{paraName:paraValue}",
dataType: "jsonp",
jsonp:'callback', //服务器端获取回调函数名的key,对应后台有$_GET['callback']='getName';callback是默认值
jsonpCallback:'getJson', //回调函数名
//beforeSend:function(x) { x.setRequestHeader("Content-Type","application/json; charset=utf-8"); },
success:function (result) { //回调函数,result,返回值
jQuery("#p2").html(result.id+result.name+result.message+"");
},
error:function(err){alert(err.textStatus);}
});
});
});
</script>
</head>
<body>
<!--<p id="p1">If you click onme, I will disappear.</p>-->
<pid="p2">getJson</p>
<!--<pid="p3">getText</p>-->
</body>
</html>