问题描述:我是用.net mvc作为服务接口供分离的前台html调用,全部用的是ajax请求,以下是ajax调用代码:
$.ajax({ type: "POST", url: "http://localhost:1750/members/login", dataType: "json", data: { 'userName': 'andy', 'password': '1q2w3e4r999' }, xhrFields: { withCredentials: true }, contentType: "application/json", success: function (result) { var objTime = eval(result) $("#apiLogin").val(objTime.data); }, error: function (XMLHttpRequest, textStatus, errorThrown) { alert(errorThrown); // 调用本次AJAX请求时传递的options参数 } })
不设置contentType时候可以跨域访问到对应action但是数据格式是ke=value格式的,不是我要的json,当设置此参数为以上内容时候,options请求是成功的,但就是报错说我的服务端
Access-Control-Allow-Origin未设置,服务端配置我也按照网上说的配置了如下内容
<httpProtocol> <customHeaders> <add name="Access-Control-Allow-Methods" value="OPTIONS,GET, POST, PUT, PATCH, DELETE, OPTIONS" /> <add name="Access-Control-Allow-Credentials" value="true" /> <add name="Access-Control-Allow-Headers" value="accept,Content-type" /> <add name="Access-Control-Expose-Headers" value="Date" /> <add name="Access-Control-Max-Age" value="1728000" /> <add name="Allow" value="POST, PUT, PATCH, DELETE" /> </customHeaders> </httpProtocol>
是的,没有配置Access-Control-Allow-Origin,这个参数我是在代码里做的,我写了一个类继承于:
public class EnableCrossAttribute : FilterAttribute, IActionFilter
实现了方法
public void OnActionExecuting(ActionExecutingContext filterContext) { string IncomingOriginHeader = "Origin"; string OutgoingOriginHeader = "Access-Control-Allow-Origin"; var isLocal = filterContext.HttpContext.Request.IsLocal; var originHeader = filterContext.HttpContext.Request.Headers.Get(IncomingOriginHeader); var response = filterContext.HttpContext.Response; if (!String.IsNullOrWhiteSpace(originHeader) && (isLocal || IsAllowedOrigin(originHeader))) { response.AddHeader(OutgoingOriginHeader, originHeader); } }
我是想让所有域名都能访问我的接口,之所以webconfig中没有配置为*,是因为xhrFields: { withCredentials: true }为true时不能配置*
现在的问题是我请求时候配置了content-type为application/json时候上面代码根本就运行不到,而webconfig里又没有配置域名,所以不能跨域,我想问1:我怎么样才能断点调试options请求,2:webconfig中的
<customHeaders>是在什么时候给添加返回的,如果我知道了这些,那么我就可以在options请求的时候给请求端
返回response.AddHeader(OutgoingOriginHeader, originHeader)我允许的域名了,或者各位有什么解决方案
解决这个跨域问题,感谢!
按照这位http://www.cnblogs.com/a546558309/p/5035471.html方式处理后,依然不行,因为一设置contenttype为“application/json”attribute那里根本就进不去,options请求返回200但是还是报错说那个域名不被允许,所以我怀疑MVC根本就不能作为复杂请求的接口,哪位大咖如果测试通过了,还望指教
2017-04-27此问题已经解决,看了http://www.developerq.com/article/1498651439这位兄台的处理,得到启发,以前一直在找把contentType改为json后是哪里处理了让其header没有返回允许的origin头,没想到在MVC的globle文件里也有这个方法
void Application_BeginRequest(object sender, EventArgs e) { if (Request.Headers.AllKeys.Contains("Origin") && Request.HttpMethod == "OPTIONS") { string domain = Request.Headers.Get("Origin"); EnableCrossAttribute df = new EnableCrossAttribute(); if (df.IsAllowedOrigin(domain)) { Response.Headers.Add("Access-Control-Allow-Origin",domain); } //Response.Flush(); Response.End(); } }
就是想找这里,来对options请求做处理,然后再结合以上过滤器的处理,至此复杂请求的跨域请求MVC支持已经完成,感谢各位的关注和帮助,谢谢
public class EnableCrossAttribute : FilterAttribute, IActionFilter
结合void Application_BeginRequest(object sender, EventArgs e)解决了问题
把Access-Control-Allow-Headers设置为*试试
!!!我设置了*后报“没有Content-type这个header”,后来我设置成了<add name="Access-Control-Allow-Headers" value="*,Content-Type" />居然好了!!,但是其他get请求却报缺少 No 'Access-Control-Allow-Origin' header is present on the requested resource错误,这个我再调试下,不过总算那个post登录的好了!!谢谢,有问题我再请教
@寂寞的博客: 不过还是建议你一下,既然用了withCredentials: true最好还是不要允许所有Origin了,你指定多个Origin不就好了。另外推荐你用这个包做跨域:Microsoft.AspNet.Cors,很方便
@balahoho: 我写这个EnableCrossAttribute作用就是哪个域名请求我就给返回的origin添加哪个允许域名,以后会改为我允许的域名的,因为配置的时候不能设置多个域名
还是没有好啊,昨天刚设置为*后登陆post好了一两次,进去网站后的get请求都是报不是允许的域名错误,到现在再试post和get又不行了,回到原来的问题了!!!.../(ㄒoㄒ)/~~
@balahoho: 你说的这个Microsoft.AspNet.Cors貌似用在asp.net webAPI里,不知mvc能用否
把 web.config 中的 Access-Control-Allow-Headers 设置去掉试试
好的我试试
简单的跨域问题可以用jsonp解决的
j就是复杂的请求,contentType 为“application/json”的post请求