Vue.js——基於$.ajax實現數據的跨域增刪查改
- 同源策略和跨域概念
- 跨域資源共享
- JSONP概念
- REST Web Services
- 基於$.ajax實現跨域GET請求
- 基於$.ajax實現JSONP請求
- 基於$.ajax實現跨域POST請求
- 基於$.ajax實現跨域PUT請求
- 基於$.ajax實現跨域DELETE請求
1.同源策略(Same-orgin policy)限制了一個源(orgin)中加載腳本或腳本與來自其他源(orgin)中資源的交互方式。
如果兩個頁面擁有相同的協議(protocol),端口(port)和主機(host),那么這兩個頁面就屬於同一個源(orgin)。
同源之外的請求都可以稱之為跨域請求。
我們可以簡單粗暴地理解為同一站點下的資源相互訪問都是同源的,跨站點的資源訪問都是跨域的
2.跨域資源共享與JSONP不同,CORS除了支持GET方法以外,還支持其他HTTP方法
3.JSONP概念
由於同源策略,一般來說不允許JavaScript跨域訪問其他服務器的頁面對象,但是HTML的<script>元素是一個例外。利用 <script> 元素的這個開放策略,網頁可以得到從其他來源動態產生的 JSON資料,而這種使用模式就是所謂的 JSONP。用 JSONP 抓到的資料並不是 JSON,而是任意的JavaScript,用 JavaScript 直譯器執行而不是用 JSON 解析器解析。
4.REST Web Services簡介
HTTP協議是Web的標准之一,HTTP協議包含一些標准的操作方法,例如:GET, POST, PUT, Delete等,用這些方法能夠實現對Web資源的CURD操作,下表列出了這些方法的操作定義。
HTTP方法 |
資源處理 |
說明 |
GET |
讀取資源(Read) |
獲取被請求URI(Request-URI)指定的信息(以實體的格式)。 |
POST |
創建資源(Create) |
在服務器上創建一個新的資源,並返回新資源的URI。 |
PUT |
更新資源(Update) |
指定URI資源存在則更新資源,指定URI資源不存在則創建一個新資源。 |
DELETE |
刪除資源(Delete) |
刪除請求URI指定的資源。 |
在REST應用中,默認通過HTTP協議,並且使用GET、POST、PUT和DELETE方法對資源進行操作,這樣的設計風格和Web標准完全契合。
REST的最佳應用場景是公開服務,使用HTTP並遵循REST原則的Web服務,我們稱之為RESTful Web Service。RESTful Web Service從以下三個方面進行資源定義:
- 直觀簡短的資源地址:URI,比如:http://example.com/resources/
- 傳輸的資源:Web Service接受與返回的互聯網媒體類型,比如JSON,XML等
- 對資源的操作:Web Service在該資源上所支持的一系列請求方法(比如:GET,POST,PUT或Delete)
下圖展示了RESTful Web Service的執行流程
AjaxHelper
基於$.ajax聲明一個簡單的AjaxHelper構造器,AjaxHelper構造器的原型對象包含5個方法,分別用於處理GET, POST, PUT, DELETE和JSONP請求。
function AjaxHelper() {
this.ajax = function(url, type, dataType, data, callback) {
$.ajax({
url: url,
type: type,
dataType: dataType,
data: data,
success: callback,
error: function(xhr, errorType, error) {
alert('Ajax request error, errorType: ' + errorType + ', error: ' + error)
}
})
}
}
AjaxHelper.prototype.get = function(url, data, callback) {
this.ajax(url, 'GET', 'json', data, callback)
}
AjaxHelper.prototype.post = function(url, data, callback) {
this.ajax(url, 'POST', 'json', data, callback)
}
AjaxHelper.prototype.put = function(url, data, callback) {
this.ajax(url, 'PUT', 'json', data, callback)
}
AjaxHelper.prototype.delete = function(url, data, callback) {
this.ajax(url, 'DELETE', 'json', data, callback)
}
AjaxHelper.prototype.jsonp = function(url, data, callback) {
this.ajax(url, 'GET', 'jsonp', data, callback)
}
AjaxHelper.prototype.constructor = AjaxHelper
實現GET請求
發送get請求
var ajaxHelper = new AjaxHelper()
var demo = new Vue({
el: '#app',
data: {
gridColumns: ['customerId', 'companyName', 'contactName', 'phone'],
gridData: [],
apiUrl: 'http://localhost:15341/api/Customers'
},
ready: function() {
this.getCustomers()
},
methods: {
getCustomers: function() {
// 定義vm變量,讓它指向this,this是當前的Vue實例
var vm = this,
callback = function(data) {
// 由於函數的作用域,這里不能用this
vm.$set('gridData', data)
}
ajaxHelper.get(vm.apiUrl, null, callback)
}
}
})
由於客戶端和服務端Web API是分屬於不同站點的,它們是不同的源,這構成了跨域請求。
這時請求是失敗的,瀏覽器會提示一個錯誤:
No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://127.0.0.1::8020' is therefore not allowed access.
跨域解決方案
現在碰到了請求跨域的問題,結合前面講的一些概念,我們大致可以猜到解決跨域請求的兩種方式:
- 在服務端啟用CORS。
- 讓無服務端擁有處理JSONP的能力。
這兩種跨域解決方案的區別是什么呢?
- JSONP只支持GET請求;CORS則支持GET、POST、PUT、DELETE等標准的HTTP方法
- 使用JSONP時,服務端要處理客戶端請求的callback參數("callback"這個名稱是可以指定的);而使用CORS則不需要提供這樣的處理。
- JSONP從服務端獲取到的是script文件;CORS則是一段XML或JSON或其他格式的數據
- JSONP支持IE8, IE9復古的瀏覽器;CORS則支持現代主流的瀏覽器
選擇JSONP還是CORS?除了極少數的情況,我們都應當選擇CORS作為最佳的跨域解決方案。