基于C#后台调用跨域MVC服务及带Cookie验证的实现
背景
随着富客户端框架的盛行,以及众多优秀的前端js框架,很多情况我们会遇到跨域的问题,而js的ajax请求是不允许直接跨域访问的,当然你会说可以用jsonp等,但是由于代码洁癖,不想在前端和后台添加callback,而且很多情况你是无法控制的,需要牵连考虑太多的情况。
所以我直接绕过了,每个前端应用,自带一个通用后端服务代理,该服务解决跨域问题,自动代理帮前台获取跨域的数据。
如何算跨域
虽然是个老问题,但是还是要提醒注意下两点:同ip,不同端口,数据访问是跨域的,但是cookie访问是可以的(这个让我很难理解)
解决,源码
cookiecontainer cookiecontainer = new cookiecontainer();
[httppost]
public string commonpost(string url)
{
log.info(cookiehelper.getcookie("itdc_username") + "进入方法commonpost url=" + url);
uri address = new uri(system.configuration.configurationmanager.appsettings["restfulapi"].tostring() + url);
httpwebrequest request = webrequest.create(address) as httpwebrequest;
request.method = "post";
request.contenttype = "application/x-www-form-urlencoded";
//远程服务,需要加入cookie验证
cookiecontainer.add(address, getcookie("itdc_username"));
cookiecontainer.add(address, getcookie("itdc_userrole"));
request.cookiecontainer = cookiecontainer;
stringbuilder data = new stringbuilder();
for (int i = 0; i < request.querystring.count; i++)
{
if (request.querystring.keys[i].tostring() == "url") continue;
data.append("&" + request.querystring.keys[i].tostring() + "=" + request.querystring[i].tostring());
}
// create a byte array of the data we want to send
byte[] bytedata = utf8encoding.utf8.getbytes(data.tostring().trimstart('&'));
// set the content length in the request headers
request.contentlength = bytedata.length;
// write data
using (stream poststream = request.getrequeststream())
{
poststream.write(bytedata, 0, bytedata.length);
}
string result = "";
using (httpwebresponse response = request.getresponse() as httpwebresponse)
{
streamreader reader = new streamreader(response.getresponsestream());
result = reader.readtoend();
}
log.info(cookiehelper.getcookie("itdc_username") + " 执行完成 commonpost url=" + url);
return (result);
}
前台调用
ext.ajax.request({url: apiurl + '/nebula/commonpost?url=/nebula/postcomment/&klid=1&msg=ok&author=admin&title=文章标题',
method: "post",
success: function (response) {
ext.viewport.unmask();
var obj = ext.decode(response.responsetext);
ext.msg.alert("提示", obj.msg, ext.emptyfn);
},
failure: function (response) {
ext.viewport.unmask();
ext.msg.alert("提示", "操作失败,请检查网络!", ext.emptyfn);
}
});