跨二级域名
我们知道cookie可以跨二级域名来访问,这个很好理解,例如你在www.cmj.com所在的web应用程序创建了一个cookie,在cs.cmj.com这样的二级域名对应的应用程序中可以访问,当然你在创建cookie的时候需要指出Domain属性为cmj.com。
跨域名问题
现在问题就是如果我不是二级域名而是完全在不同的域中,例如现在是www.smm.com想要访问www.cmj.com或其二级域名对应的程序中创建的cookie怎么办呢?我们知道至少靠常规反的方法是访问不了的,关键我们就是看看有没有方法可以访问。事实是Cookie可以在一定条件下跨域,而不是随心所欲的实现跨域。
做个实验
例如就像上面所说的有两个站点分别是www.cmj.com和www.smm.com现在就来看看如何跨域。首先按照常规我们需要有DNS服务器才能够配置域名,否则我们是无法验证的(没有域名怎么跨域啊O(∩_∩)O~),但是这里我们也没有必要那么麻烦,我们可以通过修改hosts文件来模拟。在C:/Windows/System32/drivers/etc中有hosts文件,添加上
127.0.0.1 www.cmj.com
127.0.0.1 www.smm.com
两行,就可以将本机用上面的域名访问本机回环地址了。当然,可以看出来我们只需要在iis上部署同一套程序,ip为本机回环地址,用两个域名分别访问就可以了。
那么看一下程序,我们有三个页面,其中认为cmj_index.aspx是www.cmj.com的页面,也就是说访问的地址是http://www.cmj.com/cmj_index.aspx。看一下前台代码,它没有任何后台代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="cmj_index.aspx.cs" Inherits="WebApplication1.cmj_index" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<iframe src="http://www.smm.com/smm_setCookie.aspx" mce_src="http://www.smm.com/smm_setCookie.aspx"></iframe>
</div>
</form>
</body>
</html>
另外一个是smm_setCookie.aspx这个页面,当然我们认为它是www.smm.com的页面,前台没有任何代码,这是后台代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class smm_setCookie : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
HttpCookie cookie = new HttpCookie("smmCookie");
cookie.Domain = "smm.com";
cookie.Expires = DateTime.Now.AddMinutes(10);
cookie.Values.Add("cookieInfo", "这里是cookie的值!");
Response.AppendCookie(cookie);
Response.Write("cookie已经成功创建!");
}
}
}
最后就是smm_getCookie.aspx页面了,它同样是www.smm.com下的页面,没有前台代码,只有后台代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class smm_getCookie : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.Write(Request.Cookies["smmCookie"]["cookieInfo"]);
}
}
}
我们现在要做的就是看看,当我们通过http://www.cmj.com/cmj_index.aspx之后(我们知道这时smm_setCookie页面会执行后台代码创建cookie),在http://www.smm.com/smm_getCookie.aspx中能否得到相应的cookie。如果能得到,说明在www.cmj.com下创建的cookie在www.smm.com下是可以访问到的。
首先访问一下http://www.cmj.com/cmj_index.aspx
再访问http://www.smm.com/smm_getCookie.aspx
很明显是失败的,一定条件下(其实就是将一个域中的设置cookie的操作放到frame中)的跨域也是失败的。其实是条件还不够,还需要在header中加入p3p。设置cookie的代码前加入一行代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class smm_setCookie : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
Response.AddHeader("P3P", "CP=CAO PSA OUR");
HttpCookie cookie = new HttpCookie("smmCookie");
cookie.Domain = "smm.com";
cookie.Expires = DateTime.Now.AddMinutes(10);
cookie.Values.Add("cookieInfo", "这里是cookie的值!");
Response.AppendCookie(cookie);
Response.Write("cookie已经成功创建!");
}
}
}
重复上面的访问就会发现:
具体这时为什么呢,其实因为P3P允许我们访问第三方cookie造成的,当然之所以不加不能访问是因为IE默认不支持访问第三方cookie(当然通过配置隐私信息也可以支持),其实在Firefox和chrome浏览其中默认就是支持访问第三方cookie的,当然也就不用加P3P的头信息了。这里对于P3P不做过多介绍,网上很多。
我们其实已经看到了,cookie跨域的情况,那么这是不是说明创建cookie的时候只要加入相应的头信息就可以在各种浏览器中随心所欲跨域了呢?在上面的程序的基础上添加一个页面Default.aspx,前台代码:
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1.Default" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Label ID="Label1" runat="server" Text="Cookie写入值:"></asp:Label>
<asp:TextBox ID="tbWriteValue" runat="server"></asp:TextBox>
<asp:Button ID="btnWrite" runat="server" Text="写入" οnclick="btnWrite_Click" /><br />
<asp:Label ID="Label2" runat="server" Text="Cookie读取值:"></asp:Label>
<asp:TextBox ID="tbReadValue" runat="server"></asp:TextBox>
<asp:Button ID="btnRead" runat="server" Text="读取" οnclick="btnRead_Click" /><br />
</div>
</form>
</body>
</html>
后台代码(其实和上面的代码完全一样):
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
namespace WebApplication1
{
public partial class Default : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnWrite_Click(object sender, EventArgs e)
{
Response.AddHeader("P3P", "CP=CAO PSA OUR");
HttpCookie cookie = new HttpCookie("smmCookie");
cookie.Domain = "smm.com";
cookie.Expires = DateTime.Now.AddMinutes(10);
cookie.Values.Add("cookieInfo", "这里是cookie的值!");
Response.AppendCookie(cookie);
Response.Write("cookie已经成功创建!");
}
protected void btnRead_Click(object sender, EventArgs e)
{
Response.Write(Request.Cookies["smmCookie"]["cookieInfo"]);
}
}
}
我们只需要看看在www.cmj.com中设置cookie,在www.smm.com中是否可以读取就可以了。
在www.smm.com中写入cookie
在www.smm.com中读取(肯定能读取到,在同一个域中,说明程序没错O(∩_∩)O~)
在www.cmj.com中读取
结论
好了,答案出来了。Cookie可以跨域,但是并不是只要加入头信息就可以像想象中那样跨域了,只有我们上面的情况(将一个域中的设置cookie的操作放到frame中)才可以跨域的。