解决方案

不提倡跨域的post请求。

0.jquery中ajax的跨域方案jsonp

.ashx代码

 

  1. using System; 
  2. using System.Collections.Generic; 
  3. using System.Linq; 
  4. using System.Web; 
  5.  
  6. namespace KB.DSN.Web.API.Tokens 
  7.     /// <summary> 
  8.     /// Summary description for Get 
  9.     /// </summary> 
  10.     public class Get : IHttpHandler 
  11.     { 
  12.  
  13.  
  14.         public void Proce***equest(HttpContext context) 
  15.         { 
  16.             setresponsecontext(context); 
  17.             var token = KB.DSN.BusinessAccess.UniqueCommunicationCode.GenerateUniqueCommunicationCode(); 
  18.  
  19.             var outputobject = new 
  20.             { 
  21.                 Head = new Models.KBJsonHeadResponse(), 
  22.                 Body = new { Token = token } 
  23.             }; 
  24.  
  25.             var outputjsonstring = Newtonsoft.Json.JsonConvert.SerializeObject(outputobject); 
  26.  
  27.              
  28.             context.Response.Write(context.Request.QueryString["callback"]+"("+outputjsonstring+")"); 
  29.  
  30.         } 
  31.  
  32.         private void setresponsecontext(HttpContext context) 
  33.         { 
  34.             
  35.             context.Response.ContentEncoding = System.Text.Encoding.UTF8; 
  36.             context.Response.ContentType = "application/json"
  37.         } 
  38.  
  39.         public bool IsReusable 
  40.         { 
  41.             get 
  42.             { 
  43.                 return false
  44.             } 
  45.         } 
  46.     } 




html页面

 

  1. function getToken_jsonp(){ 
  2.         $.ajax({ 
  3.    
  4.     url: "http://192.168.0.111/api/tokens/get.ashx", 
  5.           type: "get",  
  6.     dataType: "jsonp", 
  7.     jsonp: "callback", 
  8.     async: false, 
  9.      
  10.           contentType: "application/json", 
  11.           success: function(data){ 
  12.       //alert("getToken success"); 
  13.             $("#token").text($.toJSON(data)); 
  14.             //console.log(data); 
  15.        
  16.           }, 
  17.     error:function(){ 
  18.         alert("getToken fail"); 
  19.     } 
  20.         }); 
  21.  
  22.       } 

jsonp只支持GET请求,不支持POST请求,就算你写了POST,它会自动转换为GET请求,把你的data放在querystring中。

 

 

 

1.修改web.config文件

整个应用都支持跨域的请求。

web.config

  1. <system.webServer> 
  2.  
  3.   <httpProtocol> 
  4.     <customHeaders> 
  5.       <add name="Access-Control-Allow-Methods" value="OPTIONS,POST,GET"/> 
  6.       <add name="Access-Control-Allow-Headers" value="x-requested-with"/> 
  7.       <add name="Access-Control-Allow-Origin" value="*" /> 
  8.     </customHeaders> 
  9.   </httpProtocol> 
  10. </system.webServer> 

 

html page

  1. function addContact() { 
  2.            var contact = new Object(); 
  3.            contact.FirstName = $("#firstName").attr("value"); 
  4.            contact.LastName = $("#lastName").attr("value"); 
  5.            contact.PhoneNo = $("#phoneNo").attr("value"); 
  6.            contact.EmailAddress = $("#emailAddress").attr("value"); 
  7.            $.ajax({ 
  8.                url: "http://localhost:10401/api/contacts/AddContact.ashx", 
  9.                type: "POST", 
  10.  
  11.                dataType: "json", 
  12.                data: $.toJSON(contact), 
  13.   
  14.                success: function () { loadAllContacts(); } 
  15.            }); 
  16.        } 

 

 

 这种方式不能设置contentType: "application/json",否则会提示

"Request header field Content-Type is not allowed by Access-Control-Allow-Headers."

去掉ajax中的contentType设置就可以了!

 

 想要设置contentType也可以,需要将web.config文件中的

<add name="Access-Control-Allow-Headers" value="x-requested-with"/> 

修改为

<add name="Access-Control-Allow-Headers" value="x-requested-with,content-type"/> 

 

 在II6中web.config不支持system.webServer配置节,所以需要在IIS中设置httprequestheader。将web.config文件中的自定义头加入IIS的设置中。

 

FindContact.ashx

  1. /// <summary> 
  2.    /// Summary description for FindContact 
  3.    /// </summary> 
  4.    public class FindContact : IHttpHandler 
  5.    { 
  6.  
  7.        public void Proce***equest(HttpContext context) 
  8.        { 
  9.            context.Response.ContentEncoding = Encoding.UTF8; 
  10.            context.Response.ContentType = "application/json"
  11.  
  12.            var stream = context.Request.InputStream; 
  13.            var reader = new StreamReader(stream); 
  14.            var input=reader.ReadToEnd(); 
  15.  
  16.            var o = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Contact>(input); 
  17.            var list = new List<Models.Contact>(); 
  18.            list.Add(o); 
  19.            list.Add(o); 
  20.            context.Response.Write(Newtonsoft.Json.JsonConvert .SerializeObject ( list )); 
  21.        } 
  22.  
  23.        public bool IsReusable 
  24.        { 
  25.            get 
  26.            { 
  27.                return false
  28.            } 
  29.        } 
  30.    } 

 

2.在请求中设置HttpHeader

针对单个请求。

FindContact.ashx

  1. /// <summary> 
  2.    /// Summary description for FindContact 
  3.    /// </summary> 
  4.    public class FindContact : IHttpHandler 
  5.    { 
  6.  
  7.        public void Proce***equest(HttpContext context) 
  8.        { 
  9.            context.Response.ContentEncoding = Encoding.UTF8; 
  10.            context.Response.ContentType = "application/json"
  11.  
  12.            var stream = context.Request.InputStream; 
  13.            var reader = new StreamReader(stream); 
  14.            var input=reader.ReadToEnd(); 
  15.  
  16.            var o = Newtonsoft.Json.JsonConvert.DeserializeObject<Models.Contact>(input); 
  17.            var list = new List<Models.Contact>(); 
  18.            list.Add(o); 
  19.            list.Add(o); 
  20.  
  21.            #region 支持跨域请求 
  22.            context.Response.ClearHeaders(); 
  23.            string origin = context.Request.Headers["Origin"]; 
  24.            context.Response.AppendHeader("Access-Control-Allow-Origin"
  25.                string.IsNullOrEmpty(origin) ? "*" : origin); 
  26.            string requestHeaders = context.Request.Headers["Access-Control-Request-Headers"]; 
  27.            context.Response.AppendHeader("Access-Control-Allow-Headers"
  28.                string.IsNullOrEmpty(requestHeaders) ? "*" : requestHeaders); 
  29.            context.Response.AppendHeader("Access-Control-Allow-Methods""POST, OPTIONS"); 
  30.            #endregion 
  31.  
  32.            context.Response.Write(Newtonsoft.Json.JsonConvert .SerializeObject ( list )); 
  33.        } 
  34.  
  35.        public bool IsReusable 
  36.        { 
  37.            get 
  38.            { 
  39.                return false
  40.            } 
  41.        } 
  42.    } 

html page

  1. function addContact() { 
  2.            var contact = new Object(); 
  3.            contact.FirstName = $("#firstName").attr("value"); 
  4.            contact.LastName = $("#lastName").attr("value"); 
  5.            contact.PhoneNo = $("#phoneNo").attr("value"); 
  6.            contact.EmailAddress = $("#emailAddress").attr("value"); 
  7.            $.ajax({ 
  8.                url: "http://localhost:10401/api/contacts/AddContact.ashx", 
  9.                type: "POST", 
  10.  
  11.                dataType: "json", 
  12.                data: $.toJSON(contact), 
  13.   
  14.                success: function () { loadAllContacts(); } 
  15.            }); 
  16.        } 

3.使用代理

假设你有两个web应用:一个应用放html页面,给用户提供界面;一个应用放服务,使用.ASHX处理请求。

你在html应用中使用ajax请求ashx应用的接口,就是ajax跨域请求。

你可以在html应用中写一些后台代码,在代码中向ashx应用提交数据。

然后你的html应用的页面中将收集到的数据发送到html应用的后台代码中,由后台代码发送数据到ashx应用,这就不是ajax跨域请求了。

在html应用中的后台代码就被叫做“代理”,代理html应用到ashx应用的请求。

 

参考文档

1.implementing-cors-support-in-asp-net-web-apis

2.Implementing CORS support in ASP.NET Web APIs – take 2

3.说说JSON和JSONP,也许你会豁然开朗,含jQuery用例

4.Cross-Origin Resource Sharing

5.cannot POST to IHTTPHandler class, origin not allowed by Access-Control-Allow-Origin

6.Secure Cross-Domain Communication in the Browser

7.HTTP access control (CORS)

8.jQuery File Uploader, Cross Domain Requests, and ASHX Web Services

9.jquery跨域访问解决方案