一:創建一個wcf服務項目
[ServiceContract] public interface IService1 { [OperationContract] [WebInvoke(RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] string GetName(string name); }
服務可以使用WebHttpBinding以及WebGet或者WebInvoke屬性來暴露。這些屬性每一個都確定HTTP動作、消息格式以及需要暴露給一個操作的消息體形式
①WebGet屬性使用GET動詞暴露操作。GET相對於其他HTTP動作有重要的優勢。首先,通過在一個瀏覽器地址欄中輸入服務URI可以直接地訪問終結點。參數可以作為查詢字符串或者編碼字符串在URI中發送。其次,客戶端以及其他下游系統比如代理服務器可以很容易地基於緩存策略來為服務緩存資源。由於緩存能力,WebGet屬性應該只用來做收集用
②WebInvoke屬性被用於那些修改數據的添加或者刪除客戶信息的操作。最后,在WebGet和WebInvoke屬性上定義UriTemplate屬性來使用URI定義一個自定義資源
③支持的參數殘敵格式 Get類型:參數傳遞格式:{ "name": name } Post類型:參數傳遞格式:'{"name":"'+name+'"}' Post參數傳遞時必須寫成string類型
④RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json
說明傳遞近來的數據都是JSON形式的,只有兩種形式,一個是JSON,一個是XML.
⑤BodyStyle = WebMessageBodyStyle.WrappedRequest是把參數包裝一下這樣可以傳遞多個參數進來,
namespace JqueryWcfTest3 { [AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
// [JavascriptCallbackBehavior(UrlParameterName = "jsoncallback")] 作用返回值是json格式的
public class Service1 : IService1 {
//Method 請求格式,當跨域請求時必須是GET類型 [WebInvoke(Method ="GET",RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.WrappedRequest)] public string GetName(string name) { return "北京市九好市民"+name; } } }
①AspNetCompatibilityRequirements屬性確保端點使用了WEBHTTP綁定模型與webconfig中的
<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />配合使用
②OperationContract屬性把方法公開在WCF服務中
二、Web.config配置
<?xml version="1.0" encoding="utf-8"?> <configuration> <system.web> <compilation debug="true" targetFramework="4.0" /> </system.web> <system.serviceModel> <services> <!--webHttpBinding 必須要有,否則程序請求有誤 --> <service name="JqueryWcfTest3.Service1"> <endpoint address="" binding="webHttpBinding" contract="JqueryWcfTest3.IService1" behaviorConfiguration="AllenBehavior"/> </service> </services> <behaviors> <endpointBehaviors> <behavior name="AllenBehavior"> <enableWebScript/> <!--JavaScript 訪問,必須要有--> </behavior> </endpointBehaviors> <serviceBehaviors> <behavior> <!-- 為避免泄漏元數據信息,請在部署前將以下值設置為 false --> <serviceMetadata httpGetEnabled="true" httpsGetEnabled="true"/> <!-- 這個必須要有,可以查看錯誤信息 --> <serviceDebug includeExceptionDetailInFaults="true"/> </behavior> </serviceBehaviors> </behaviors> <serviceHostingEnvironment aspNetCompatibilityEnabled ="true"> <!--serviceActivations 添加一個指定激活服務應用程序的配置元素, 這里要配置服務激活相關的選項:--> <serviceActivations> <!-- relativeAddress是相對地址,service是我們定義的服務的名字,記住這里不要把service設置為契約名字,否則會出現錯誤。--> <add relativeAddress="JqueryWcfTest3.Service1.svc" service="JqueryWcfTest3.Service1" factory="System.ServiceModel.Activation.WebScriptServiceHostFactory" /> </serviceActivations> </serviceHostingEnvironment> </system.serviceModel> </configuration>
三、本地請求Html頁面
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title></title> <script src="jquery-1.10.2.js"></script> <meta charset="utf-8" /> <script> $(function() { $.ajax({ type: "post", url: "/Service1.svc/GetName", dataType: 'text/json', contentType:"application/json", data:'{"name":"xiaoyao"}', success: function (data) { console.log(data); }, error: function (txt) { console.log(txt); } }); }) </script> </head> <body> </body> </html>
結果
四、跨域請求
$.ajax({ type: "get", url: "http://localhost:49719/Service1.svc/GetName?name=xiaoyao", dataType: 'jsonp', jsonp: "callback", contentType: "application/json", success: function (data) { console.log(data); }, error: function (txt) { console.log(txt); } });
注釋:
Jaxa可以進行跨域請,但僅限於GET請求方式,並且數據格式是jsonp形式的
JSONP是一個非官方的協議,它允許在服務器端集成Script tags返回至客戶端,通過javascript callback的形式實現跨域訪問(這僅僅是JSONP簡單的實現形式)要點就是允許用戶傳遞一個callback參數給服務端,然后服務端返回數據時會將這個callback參數作為函數名來包裹住JSON數據,這樣客戶端就可以隨意定制自己的函數來自動處理返回數據了。
1、ajax和jsonp這兩種技術在調用方式上“看起來”很像,目的也一樣,都是請求一個url,然后把服務器返回的數據進行處理,因此jquery和ext等框架都把jsonp作為ajax的一種形式進行了封裝;
2、但ajax和jsonp其實本質上是不同的東西。ajax的核心是通過XmlHttpRequest獲取非本頁內容,而jsonp的核心則是動態添加<script>標簽來調用服務器提供的js腳本。
3、所以說,其實ajax與jsonp的區別不在於是否跨域,ajax通過服務端代理一樣可以實現跨域,jsonp本身也不排斥同域的數據的獲取。
4、還有就是,jsonp是一種方式或者說非強制性協議,如同ajax一樣,它也不一定非要用json格式來傳遞數據,如果你願意,字符串都行,只不過這樣不利於用jsonp提供公開服務。
json與jsonp數據格式的區別
Json格式 { "method":"get", "result":"ok" } jsonp格式 callback({ "method":"get", "result":"ok" })
錯誤提示
①異常消息為“傳入消息的消息格式不應為“Raw”。此操作的消息格式應為 'Xml', 'Json'
在最后$.ajax中添加--contentType: "application/json",即可...
②415 Cannot process the message because the content type 'application/x-www-form-urlencoded' was not the expected type 'text/xml; charset=utf-8'"
需要在Web.config中綁定webHttpBinding
③遇到了無效消息正文。預期找到名為“type”、值為“object”的特性,但找到的值為“null”
data:'{"name":"xiaoyao"}' data必須要傳string類型,不能是字典以及實體