㈠ js調用跨域get請求調用webApi 多出個options請求是為什麼
我嘗試用我的語言描述一下吧:
先說跨域請求的原理,瀏覽器的安全機制是不允許出現跨域請求的,否則會有很嚴重的安全問題,解決跨域問題有幾種不同的方法,你題目中提到的方法就是通過在Response header中添加Access-Control-Allow-Origin 來讓瀏覽器知道伺服器所在的域,對用於訪問的域進行了授權。
但是因為這個Header要伺服器提供,所以無論如何,請求是要先發出去才能指導是不是允許跨域請求,所以在報跨域錯誤的時候,雖然報錯了,但是請求實際上依然發送到伺服器了,只是瀏覽器看了一眼伺服器的返回,然後發覺不行,這個請求返回的header里沒有授權,所以瀏覽器不能用。
這樣就帶來一個問題,請求會對伺服器造成影響,試想一下,要使用XHR跨域提交一個表單,無論返回頭裡面是否添加了跨域的header,都會提交一個請求到伺服器,伺服器要進行相應的操作。這種情況其實在一定條件下也是可以接受的,但是如果有更大的安全隱患,就不可以了,所以就需要OPTIONS請求了。
OPTIONS請求就是在符合一定條件下的跨域請求發送之前,瀏覽器會先發一個OPTIONS請求,問一下伺服器,是不是能跨域,如果能,就發真正的請求,如果不能,就不發了。這個的作用就很好理解了。
如上面所說,不是所有的跨域請求都要先發OPTIONS請求的,規范裡面規定,以下情況不需要先發一個 OPTIONS請求:
請求類型必須是GET、HEAD、POST中的一種。
請求的Header裡面只能包涵一些規范重點Header,以及規范的值,包括:Accept、Accept-Language、Content-Language、Content-Type、DPR、Downlink、Save、Data、Viewport-Width、Width
Content-Type的類型必須是以下幾種:application/x-www-form-urlencoded、multipart/form-data、text/plain
所以,如果你不希望瀏覽器多餘的發一個OPTIONS請求,只要遵循這個規范就可以了。
但是有時候因為需求原因,也難避免要自定義一些Header。比如,很多JS的AJAX庫,都會自定義一個Header,讓伺服器可以識別出這是否是一個非同步請求,這樣OPTIONS請求就一定要被先發送了。
順便說,伺服器端也要判斷OPTIONS類型的請求,進行一系列操作,不要讓OPTIONS請求影響到數據。
更多內容,可以看相關資料和文檔:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS
https://developer.mozilla.org/en-US/docs/Web/HTTP/Server-Side_Access_Control
https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html
㈡ JAVA調用WEBAPI查看客戶信息失敗,怎麼辦
設置的內容如下
Kingdee.BOS.WebApi.ServicesStub.DynamicFormService.View.common.kdsvc
BD_Customer
{"CreateOrgId":100040,"Number":"001.001.0001"}
返回的錯誤信息如下
{"Result":{"ResponseStatus":{"ErrorCode":500,"IsSuccess":false,"Errors":[{"FieldName":"給定關鍵字不在字典中。","Message":" 在 System.Collections.Generic.Dictionary`2.get_Item(TKey key)\r\n 在 Kingdee.BOS.WebApi.FormService.View.Execute()\r\n 在 Kingdee.BOS.WebApi.FormService.BillOperationService.ExecuteOperation(FormOperation op, String data)"}],"SuccessEntitys":[]}}}
修改傳入參數,把Id補上(不知道Id值),如下
{"CreateOrgId":100040,"Number":"001.001.0001","Id":"String"}
此時返回的錯誤信息如下
{"Result":{"ResponseStatus":{"ErrorCode":500,"IsSuccess":false,"Errors":[{"FieldName":"輸入字元串的格式不正確。","Message":" 在 System.Number.StringToNumber(String str, NumberStyles options, NumberBuffer& number, NumberFormatInfo info, Boolean parseDecimal)\r\n 在 System.Number.ParseInt64(String value, NumberStyles options, NumberFormatInfo numfmt)\r\n 在 Kingdee.BOS.WebApi.FormService.View.Execute()\r\n 在 Kingdee.BOS.WebApi.FormService.BillOperationService.ExecuteOperation(FormOperation op, String data)"}],"SuccessEntitys":[]}}}
㈢ 請問html的js調用webapi介面
引用jquery,有很方便的GET調用方法:
<!DOCTYPEhtml>
<html>
<head>
<metahttp-equiv="content-type"content="text/html;charset=UTF-8">
<metaname="viewport"content="width=device-width,initial-scale=1">
<!--src值為文件位置路徑-->
<scripttype="text/javascript"charset="UTF-8"src="javascript/jquery-1.12.1.js"></script>
<title>測試案例</title>
<!--語法:jQuery.getJSON(url,data,success(data,status,xhr))-->
<scripttype="text/javascript"charset="UTF-8">
functiongetToken(){
$.getJSON("http://localhost/kdapi/api/access_token",{"id":111,"secret":2352532},function(result){
alert(result.access_token);
});
}
</script>
</head>
<body>
<buttononclick="getToken()"style="width:120px;height:60px;">獲取Token</button>
</body>
</html>
㈣ 如何使用程序調用webApi介面
functiongetAPI(url){
returnnewPromise((resolve,reject)=>{
$.ajax({
url:url,
type:'GET',
dataType:'json',
data:{param1:'value1'},
})
.done(function(data){
resolve({data:data})
})
});
}
let_api=awaitthis.getAPI(url);
這是我用ES6與非同步方式寫的url就是調用的API地址