频道栏目
首页 > 资讯 > JavaScript > 正文

Vue.js——基于$.ajax实现数据的跨域增删查改

16-07-07        来源:[db:作者]  
收藏   我要投稿

之前我们学习了Vue.js的一些基础知识,以及如何开发一个组件,然而那些示例的数据都是local的。
在实际的应用中,几乎90%的数据是来源于服务端的,前端和服务端之间的数据交互一般是通过ajax请求来完成的。

说起ajax请求,大家第一时间会想到jQuery。除了拥有强大的DOM处理能力,jQuery提供了较丰富的ajax处理方法,它不仅支持基于XMLHttpRequest的ajax请求,也能处理跨域的JSONP请求。

之前有读者问我,Vue.js能结合其他库一起用吗?答案当然是肯定的,Vue.js和jQuery一起使用基本没有冲突,尽可放心大胆地使用。

本文的主要内容如下:

同源策略和跨域概念 跨域资源共享 JSONP概念 REST Web Services 基于$.ajax实现跨域GET请求 基于$.ajax实现JSONP请求 基于$.ajax实现跨域POST请求 基于$.ajax实现跨域PUT请求 基于$.ajax实现跨域DELETE请求

本文的服务端程序和客户端程序是部署在不同服务器上的,本文所有示例请求都是跨域的。
源代码已放到GitHub,如果您觉得本篇内容不错,请点个赞,或在GitHub上加个星星!

CORS GET JSONP GET CORS POST CORS PUT 完整CURD示例 GitHub Source 基础概念

在进入本文正题之前,我们需要先了解一些基础概念(如果你已经对这些基础有所了解,可跳过此段落)。

同源策略和跨域概念

同源策略(Same-orgin policy)限制了一个源(orgin)中加载脚本或脚本与来自其他源(orgin)中资源的交互方式。
如果两个页面拥有相同的协议(protocol),端口(port)和主机(host),那么这两个页面就属于同一个源(orgin)。

同源之外的请求都可以称之为跨域请求。
下表给出了相对http://store.company.com/dir/page.html同源检测的示例:

URL 结果 原因 http://store.company.com/dir2/other.html 成功 http://store.company.com/dir/inner/another.html 成功 https://store.company.com/secure.html 失败 协议不同 http://store.company.com:81/dir/etc.html 失败 端口不同 http://news.company.com/dir/other.html 失败 主机名不同

我们可以简单粗暴地理解为同一站点下的资源相互访问都是同源的,跨站点的资源访问都是跨域的。 跨域资源共享

跨域资源共享(CORS)是一份浏览器技术的规范,提供了Web服务器从不同网域传来沙盒脚本的方法,以避开浏览器的同源策略,是JSONP模式的现代版。与JSONP不同,CORS除了支持GET方法以外,还支持其他HTTP方法。用CORS可以让网页设计师用一般的XMLHTTPRequest,这种方式的错误处理比JSONP要来的好。另一方面,JSONP可以在不支持CORS的老旧浏览器上运作,现代的浏览器都支持CORS。

在网页http://caniuse.com/#feat=cors上列出了主流浏览器对CORS的支持情况,包含PC端和移动端的浏览器。

image JSONP概念

由于同源策略,一般来说不允许JavaScript跨域访问其他服务器的页面对象,但是HTML的 创建和注册modal-dialog组件

数据的新建和编辑将使用模态对话框,modal-dialog组件的作用就在于此。




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.

image

跨域解决方案

现在碰到了请求跨域的问题,结合前面讲的一些概念,我们大致可以猜到解决跨域请求的两种方式:

在服务端启用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作为最佳的跨域解决方案。

启用CORS

在Nuget Package Manager Console下输入以下命令:

Install-Package Microsoft.AspNet.WebApi.Cors

在CustomersController上添加EnableCors特性,origins、headers和methods都设为*

[EnableCors(origins: "*", headers: "*", methods: "*")]
public class CustomersController : ApiController
{
 
}

Web API的各项配置说明及原理,下面这个地址已经讲得很清楚了:
http://www.asp.net/web-api/overview/security/enabling-cross-origin-requests-in-web-api

刷新页面,现在数据可以正常显示了。

image

View Demo

在Chrome开发工具的Network选项下,可以看到Response Header的Content-Type是application/json。

image

文章开头也说了,CORS的跨域方式支持现代的主流浏览器,但是不支持IE9及以下这些古典的浏览器。

image

如果我们偏要在IE9浏览器中(Vue.js不支持IE8及以下的浏览器,所以不考虑IE 6,7,8)实现跨域访问,该怎么做呢?
答案是使用JSONP请求。

实现JSONP请求

将getCustomers方法的get请求变更为jsonp请求:

getCustomers: function() {
	// 定义vm变量,让它指向this,this是当前的Vue实例
	var vm = this,
		callback = function(data) {
			// 由于函数的作用域,这里不能用this
			vm.$set('gridData', data)
		}
	ajaxHelper.jsonp(vm.apiUrl, null, callback)
}

刷新页面,请求虽然成功了,但画面没有显示数据,并且弹出了请求错误的消息。

image

让WebAPI支持JSONP请求

在Nuget Package Manager中输入以下命令:

Install-Package WebApiContrib.Formatting.Jsonp

然后在Global.asax的Application_Start()方法中注册JsonpMediaTypeFormatter:

// 注册JsonpMediaTypeFormatter,让WebAPI能够处理JSONP请求
config.Formatters.Insert(0, new JsonpMediaTypeFormatter(jsonFormatter));

刷新页面,使用JSONP请求也能够正常显示数据了。

image

image

注意:使用JSONP时,服务端返回的不再是一段JSON了,而是一个script脚本。

在IE9下查看该页面,simple-grid组件也能正常显示数据:

image

View Demo

实现POST请求 1. 创建表单对话框

添加一个Create按钮,然后使用modal-dialog组件创建一个表单对话框:


	
		
	
	

Create New Customer

注意:在新建Customer时,由于item.customerId为空,所以item.customerId关联的表单不会显示;在修改Customer时,item.customerId关联的表单会显示出来。另外,item.customerId是不可编辑的。

2. 修改Vue实例
var demo = new Vue({
	el: '#app',
	data: {
		show: false,
		gridColumns: [{
			name: 'customerId',
			isKey: true
		}, {
			name: 'companyName'
		}, {
			name: 'contactName'
		}, {
			name: 'phone'
		}],
		gridData: [],
		apiUrl: 'http://localhost:15341/api/Customers',
		item: {}
	},
	ready: function() {
		this.getCustomers()
	},
	methods: {
		// ... 已省略
		createCustomer: function() {
			var vm = this,
				callback = function(data) {
					vm.$set('item', {})
						// 添加成功后,重新加载页面数据
					vm.getCustomers()
				}
				// 将vm.item直接POST到服务端
			ajaxHelper.post(vm.apiUrl, vm.item, callback)
			this.show = false
		}
	}
})

修改Vue实例的data选项:

添加show属性:用于显示或隐藏表单对话框 修改gridColumns属性:列包含两个属性,name表示列名称,isKey表示列是否为主键列 添加item属性:用于新增Customer或修改Customer

添加createCustomer方法:

createCustomer: function() {
	var vm = this,
		callback = function(data) {
			vm.$set('item', {})
			// 添加成功后,重新加载页面数据
			vm.getCustomers()
		}
		// 将vm.item直接POST到服务端
		ajaxHelper.post(vm.apiUrl, vm.item, callback)
		this.show = false
}

24

View Demo

实现PUT请求 1. 修改sample-grid的template

给主键列添加链接,绑定click事件,事件指向loadEntry方法,loadEntry方法用于加载当前选中的数据。


相关TAG标签
上一篇:CSS制作彩虹效果
下一篇:Jquery属性获取——attr()与prop()
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站