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作为最佳的跨域解决方案。