与服务器端通信
Vue.js 可以构建一个完全不依赖后端服务的应用,同时也可以与服务端进行数据交互来同步界面的动态更新。Vue 本身并没有提供与服务端通信的接口,但是通过插件的形式实现了基于AJAX、JSONP 等技术的服务端通信。
vue-resource 是一个通过 XMLHttpRequest 或 JSONP 技术实现异步加载服务端数据的 Vue 插件,该插件提供了一般的 HTTP 请求接口和 RESTful 架构请求接口,并且提供了全局方法和 Vue 组件实例方法。
一般的 HTTP 请求接口按照调用的便捷程度又分为底层方法和 便捷方法,便捷方法是对底层方法的封装。在 vue-resource 中我们可以全局配置,同时,它提供了数据获取各个阶段的钩子,使得我们可以对数据获取过程进行更好的控制。
vue-resource 安装及配置
1、安装
vue-resource 提供了 npm、bower、手动编译等安装方式,可以根据业务需要选择其中一种方式进行安装。
1-1、npm
如果项目基于 npm 包方式来开发,则可以使用 npm 来按照 vue 和 vue-resource,执行如下命令
$ npm i vue vue-resource --save-dev
然后在项目中引入 Vue.js 和 vue-resource,并且在 Vue.js 中注册 vue-resource 插件,代码如下:
// 引入 Vue.js 和vue-resource var Vue = require('vue'); var VueResource = require('vue-resource'); // 注意,假如 Vue.js 已经在html 中直接引入,则不需要再执行此步骤 // 此时vue-resource 会自动调用 Vue.use 方法来注册 Vue.use(VueResource); |
1-2、bower
当业务代码使用 bower 来管理时,可以使用 bower 安装到指定目录。假如该目录为 js/vendor,执行如下命令:
$ bower install vue-resource
在 HTML 中,在 vue 文件之后引入 vue-resource,代码如下:
<!-- 引入 Vue--> <script src="js/vendor/vue.js"></script> <!-- 引入 vue-resource --> <script src="js/vendor/vue-resource.js"></script> |
1-3、手动编译
当想尝试一些 Vue 中并未发布的新特性时,可以直接 clone 源码,手动构建实现。由于在未正式发布之前,有些特性可能被移除,所以不建议在生产环境中使用手动编译方式安装。
没有安装 git 工具的,可参照百度提供的步骤并解决安装过程中遇到的相关问题
http://jingyan.baidu.com/article/d2b1d1029065ba5c7e37d43e.html?st=2&os=0&bd_page_type=1&net_type=
执行命令如下:
$ git clonehttps://github.com/pagekit/vue-resource
$ cd vue-resource
$ npm install
$ npm run build
在C盘对应的目录下就生成了一系列的 vue-resource 文件
2、参数配置
vue-resource 将请求配置分为全局配置、组件实例配置和调用配置 三部分,这三部分的优先级依次增高,优先级高的配置会覆盖优先级低的配置。
全局配置默认参数,如图:
2-1、全局配置
Vue.http.options.root='/root'; Vue.http.headers.common['Authorization']='BasicYXBpOnBhc3N3b3Jk';
2-2、组件实例配置
在实例化组件时,可以传入 http 选项来进行配置
newVue({ http:{ root:'/root',headers:{ Authorization:'BasicYXBpOnBhc3N3b3Jk' } } })
newVue({ ready:function(){ //get请求 this.$http.get({url:'/someUrl',headers:{Authorization:'BasicYXBpOnBhc3N3b3Jk'}}) .then(function(successResponse){ //请求成功的回调函数 },function(errorResponse){ //请求失败的回调函数 } ) } })
3、headers 配置
headers 属性用来配置请求头。合并策略遵循参数配置合并策略。除了参数配置 headers 属性可以设置请求头外,在 vue-resources 中也提供了全局默认的 headers 配置
其中 common 对应的请求头会在所有请求头中设置,custom 对应的请求头在非跨域时设置,HTTP 方法名对应的请求头只有在请求的 method 匹配方法名时才会被设置。
4、基本 HTTP 调用
基本 HTTP 调用即普通的 GET、POST 等基本的 HTTP 操作,实际上执行增、删、改、查是前后端开发人员共同约定的,并非通过 HTTP 的请求方法如 GET 代表获取数据、PUT代表写入数据、POST 代表更新数据。
4-1、底层方法
全局的 Vue.http 方法和Vue 组件的实例方法 this.$http 都属于底层方法,它们根据所传 option 参数的 method 属性来判断请求方式是 GET 还是 POST,或者是其它合法的 HTTP 方法
(1)、全局调用 this -> window
//globalVueobject Vue.http.get('/someUrl',[options]).then(successCallback,errorCallback); Vue.http.post('/someUrl',[body],errorCallback);
(2)、组件实例调用 this -> Vue 实例
//inaVueinstance this.$http.get('/someUrl',errorCallback); this.$http.post('/someUrl',errorCallback);
以组件实例调用方式为例来了解一下如何发送 POST 请求,代码如下:
newVue({ ready:function(){ //POST请求 this.$http({ url:'/book',method:'POST',//请求体中发送的数据 data:{ cat:'1' },//设置请求头 headers:{ 'Content-Type':'x-www-form-urlencoded' } }).then( function(response){ //请求成功回调 },function(response){ //请求失败回调 } ) } })
示例一:
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,initial-scale=1"> <linkhref="//cdn.bootcss.com/bootstrap/3.0.1/css/bootstrap.css"rel="stylesheet"> <title></title> </head> <body> <divid="app"> <inputclass="btnbtn-success"type="button"value="按钮"@click="get()"> </div> <scriptsrc="//cdn.bootcss.com/vue/2.0.8/vue.js"></script> <scriptsrc="//cdn.bootcss.com/vue-resource/0.7.2/vue-resource.js"></script> <script> newVue({ el:'#app',data:{ },methods:{ get:function(){ this.$http.get('aa.txt').then(function(res){ alert(res.data); },function(res){ alert(res.status); }); } } }); </script> </body> </html>
在同级目录下,新建一个“aa.txt”,并写上一段文本“welcome vue-----”,用Apche服务器打开网页,点击按钮以后
成功请求到了 aa.txt,并拿到了响应数据。如果响应失败,就会弹出响应失败的状态码 status,比如把 aa.txt 改成 bb.txt,就会报404 错误
示例二:
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,methods:{ get:function(){ this.$http.get('get.PHP',{ a:1,b:2 }).then( function(response){//成功的回调函数 alert(response.data); },function(response){//失败的回调函数 alert(response.status); } ) } } }); </script> </body> </html>
<?PHP $a=$_GET['a']; $b=$_GET['b']; echo$a+$b; ?>
点击按钮以后,发起一个 get 请求,如果请求成功则返回 a+b的结果,如果请求失败则返回对应的状态码
4-2、便捷方法
不同于底层方法,便捷方法是对底层方法的封装,在调用时可以省去配置选项 option 中的method 属性。以下是 vue-resource 提供的便捷方法列表:
get(url,[options])
head(url,0);">delete(url,0);">jsonp(url,0);">post(url,0);">put(url,0);">patch(url,[options])
options 参数列表
参数 |
类型 | 描述 |
url |
string | 请求的 URL 地址 |
body | Object,FormData,string | 请求体 |
headers | Object | HTTP请求头部 |
params | Object |
URL参数,默认值为{} Vue.http({ url:'http://example.com/{book}', params:{ book:'vue','Microsoft YaHei';"> cat:'1' } }) 最终URL为 http://example.com/vue?cat=1 |
method |
请求的HTTP方法(GET、POST等),默认GET | |
timeout | number | 请求超时时间,默认值为0,单位是ms,0表示没有超时限制,超时后将会取消当前请求 |
before |
function(request) | 请求发送前的处理函数。默认值为null,接受请求选项对象作为参数 |
progress | function(event) | 处理ProgressEvent的回调函数 |
credentials | boolean |
表示跨域请求时是否需要使用凭证 |
emulateHTTP | boolean | 默认值为false,当值为true时,用HTTP的POST方法发送PUT、PATCH、DELETE等请求,并设置请求头字段 HTTP-Method-Override为原始请求方法 |
emulateJSON | boolean | 默认值为false,当值为true并且data为对象时,设置请求头Content-Type的值为 application/x-www-form-urlencoded |
xhr | Object | 默认值为null,该对象中的属性都会应用到原生xhr实例对象上 |
upload | 默认值为null,该对象的属性都会应用到原生xhr实例对象的upload属性上 | |
jsonp | string | 默认值为callback,JSONP请求中回调函数的名 字 url:'http://example.com/book','Microsoft YaHei';">method:'JSONP','Microsoft YaHei';">jsonp:'cb' }) |
crossOrigin | 默认值为null,表示是否跨域,如果没有设置该属性,vue-resource 内部会判断浏览器当前 URL 和请求 URL 是否跨域 |
示例代码:
<?PHP $a=$_POST['a']; $b=$_POST['b']; echo$a-$b; ?>
把 emulateJSON的值改为 true,运行代码
把 emulateJSON的值改为默认值false 或者去掉“{emulateJSON:true}”,运行代码,报错了
5、response 对象
response 对象包含服务端返回的数据,以及 HTTP 响应状态、响应头等信息。
属性 |
类型 | 描述 |
url |
string | 响应的 URL |
body | 响应体数据 | |
headers | Header | 响应头对象 |
ok | boolean | HTTP 状态码(200-299之间) |
status | number | HTTP 响应状态码 |
statusText | HTTP 响应文本 | |
data | Object,string | 服务器端返回的数据,已使用JSON.parse解析 |
方法 | 类型 | 描述 |
text( ) | Promise | 把响应数据解析为字符串 |
json( ) | 把响应数据解析为JSON对象 | |
blob( ) | Promise | 把响应数据解析为二进制对象 |
示例代码如下:
{//POST/someUrl this.$http.post('/someUrl',{foo:'bar'}).then((response)=>{ //getstatus response.status; //getstatustext response.statusText; //get'Expires'header response.headers.get('Expires'); //setdataonvm this.$set('someData',response.body); },(response)=>{ //errorcallback }); }
从响应对象中获得一个 image并使用blob() 方法提取image的数据内容
{ //GET/image.jpg this.$http.get('/image.jpg').then((response)=>{ //resolvetoBlob returnresponse.blob(); }).then(blob)=>{ //useimageBlob }); }
6、拦截器(Interceptors)可以全局进行拦截设置,拦截器可以在请求发送前或响应返回时做一些特殊的处理
6-1、处理请求消息
Vue.http.interceptors.push((request,next)=>{ //modifyrequest request.method='POST'; //continuetonextinterceptor next(); });
6-2、处理请求和响应消息
Vue.http.interceptors.push((request,next)=>{ //modifyrequest request.method='POST'; //continuetonextinterceptor next((response)=>{ //modifyresponse response.body='...'; }); });
6-3、返回一个响应消息并停止处理
Vue.http.interceptors.push((request,next)=>{ //modifyrequest... //stopandreturnresponse next(request.respondWith(body,{ status:404,statusText:'Notfound' })); });
7、跨域 AJAX
很多人认为 AJAX 只能在同域的情况下发送成功,很早的时候,由于浏览器安全策略,AJAX确实只能在同域的情况下发送。但是目前很多浏览器已经开始支持 XMLHttpRequest2,XMLHttpRequest2引入了大量的新特性,例如跨域资源请求(CORS)、上传进度事件、支持二进制数据上传/下载等。
这里初步了解下 vue-resource 中用到的 CORS 特性,以及 XMLHttpRequest2 的替代品 XDomainRequest
7-1、XMLHttpRequest2 CORS
XMLHttpRequest2 是第二代 XMLHttpRequest 技术,提交 AJAX请求还是和普通的 XMLHttpRequest 请求一样,只是增加了一些新特性。
在提交AJAX 跨域请求时,首先我们需要知道当前浏览器是否支持 XHR2,判断方法是使用 in 操作符检测当前 XHR实例对象是否包含 widthCredentials 属性,如果包含则支持 CORS。
varxhrCors='withCredentials'innewXMLHttpRequest();
在支持 CORS 的情况下,还需要服务端启用 CORS 支持。
假如我们想从 http://example.com域中提交请求到 http://crossdomain.com域,那么需要在 crossdomain.com 域中添加如下响应头:
Access-Control-Allow-Origion:http://example.com
如果crossdomain.com 要允许所有异域都可以 AJAX 请求该域资源,则添加如下响应头
Access-Control-Allow-Origion:*
服务端开启 CORS 支持后,在浏览器中我们就可以和提交普通的 AJAX 请求一样提交跨域请求了。
varxhrCors='withCredentials'innewXMLHttpRequest(); console.log(xhrCors); varxhr=newXMLHttpRequest(); xhr.open('GET','http://www.crossdomain.com/hello.json'); xhr.onload=function(e){ vardata=JSON.parse(this.response); //... }; xhr.send();
7-2、XDomainRequest
如果想在 IE8、IE9中支持 CORS(IE10及以后版本支持 XHR2),我们可以使用 XDomainRequest(该属性目前已经废弃,不建议使用)。如果 vue-resource 不支持 XHR2,则会降级使用此种方式。
//实例化XDomainRequest varxdr=newXDomainRequest(); xdr.open('get','http://www.crossdomain.com/hello.json'); xdr.onprogress=function(){ //进度回调 }; xdr.ontimeout=function(){ //超时回调 }; xdr.onerror=function(){ //出错回调 }; xdr.onload=function(){ //成功回调 //success(xdr.responseText) }; setTimeout(function(){ //发送请求 xdr.send(); },0)
注意:XDomain 只支持 GET 和 POST 两种请求,如果要在 vue-resource 中使用其他方法请求,需设置请求选项对象的 emulateHTTP 为true。在定时器中调用 xhr.send( )方法,是为了防止多个 XDomainRequest 请求同时发送时部分请求丢失。
8、Promise
vue-resource 调用 action 方法执行后都会返回一个 Promise 对象,该 Promise 对象提供了 then,catch,finally 等常用方法来注册回调函数
varpromise=this.$http.post( 'http://example.com/book/create',//请求体中要发送给服务端的数据 { cat:'1',name:'newbook' },{ 'headers':{ 'Content-Type':'x-www-form-urlencoded' } } ); promise.then( function(response){ //成功回调 console.log(response.data); },function(response){ //失败回调 console.log('somethingwrong'); } ); promise.catch(function(response){ //失败回调 console.log('somethingwrong'); }); promise.finally(function(response){ //执行完成或者失败回调后都会执行此逻辑 })
:所有回调函数的this 都指向组件实例
常见问题解析
1、如何发送 JSONP 请求
首先我们需要知道 JSONP 是利用 Javascript 可以跨域的特性从服务端请求数据的,也就是说,在跨域的情况下才有必要使用 JSONP来发送请求。vue-resource 提供了三种调用方式
1-1、全局方法
Vue.http({ url:'http://example.com/books',//参数部分,将会拼接在url之后 params:{ cat:'1' },method:'JSONP' }).then(function(response){ //response.data为服务端返回的数据 console.log(response.data); }).catch(function(response){ //出错处理 console.log(response) })
1-2、实例底层方法
this.$http({ url:'http://example.com/books','Microsoft YaHei';">1-3、实例便捷方法this.$http.jsonp( 'http://example.com/books',//参数部分,将会拼接在url之后 { cat:'1' } ).then(function(response){ //response.data为服务端返回的数据 console.log(response.data); }).catch(function(response){ //出错处理 console.log(response) })先打开 www.so.com进入360 好搜的主页面,打开network查看页面请求,在搜索框中随便输入一个字母 v,获取请求发送的 url
按照图中的步骤获取 url ,并截取 只包含回调函数 callback 和 关键字的字段
https://sug.so.360.cn/suggest?callback=suggest_so&word=v
在浏览器中打开这个链接,查看输入关键字 v,360搜索给出的搜索建议,可以看到所有的搜索建议关键词都存放在 s 这个数组中
我们现在想要实现的效果就是在我们的页面中,点击一个按钮就可以获取到上图中所有与 v 相关的关键词
代码如下:
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,initial-scale=1"> <linkhref="//cdn.bootcss.com/bootstrap/3.0.1/css/bootstrap.css"rel="stylesheet"> <title></title> </head> <body> <divid="app"> <inputclass="btnbtn-primary"type="button"value="按钮"@click="get"> </div> <scriptsrc="//cdn.bootcss.com/vue/2.0.8/vue.js"></script> <scriptsrc="//cdn.bootcss.com/vue-resource/0.7.2/vue-resource.js"></script> <script> varvm=newVue({ el:'#app',methods:{ get:function(){ this.$http.jsonp('https://sug.so.360.cn/suggest',{word:'v'}) .then( function(response){//响应成功的回调函数 alert(response.data.s);//关键词存放在data数据的s数组里面 },function(response){//响应失败的回调函数 alert(response.status) } ) } } }) </script> </body> </html>点击按钮,发起 JSONP 请求,拿到了所有的关键词
示例代码二:获取百度的关键词同样的方法,打开 www.baidu.com,打开控制台、进入 network,获取 url
按照图中的步骤获取 url ,并截取 只包含回调函数 callback 和 关键字的字段。问题出现了,与360搜索不同的是,百度搜索的回调函数名称是 cb,不是callback
https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=v&cb=jQuery110208886270477889466_1480905136502
在浏览器中打开这个链接,查看输入关键字 v,百度搜索给出的搜索建议,可以看到所有的搜索建议关键词都存放在 s 这个数组中
示例代码:
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,methods:{ get:function(){ this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su',{wd:'v'}) .then( function(response){//响应成功的回调函数 alert(response.data.s);//关键词存放在data数据的s数组里面 },'Microsoft YaHei';">同样的代码,但是运行之后并没有得到预期的结果,而是报错了:无法读取未定义的 sug 属性回忆下 4-2 options 参数列表中提到的 jsonp 默认值是 callback,再看看上面带下划线的文字,我们很快发现,百度中 回调函数的名称是cb,因此这里需要做一点小改动
varvm=newVue({ el:'#app',{wd:'v'},{jsonp:'cb'}) .then( function(response){//响应成功的回调函数 alert(response.data.s);//关键词存放在data数据的s数组里面 },function(response){//响应失败的回调函数 alert(response.status) } ) } } })现在就都可以获取了
基于前面的两个例子,我们可以做一个稍微有点实用价值的demo,在页面中放一个搜索框,无论输入什么关键词,都能获取到百度的搜索建议
几个注意点:
(1)、input输入的内容不再是固定的字母 v,而是通过动态双向绑定到url中
(2)、当下拉列表的列表为0时,出现“暂无数据”提示
(3)、事件触发使用keyup(),按键松开时触发
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,initial-scale=1"> <linkhref="//cdn.bootcss.com/bootstrap/3.0.1/css/bootstrap.css"rel="stylesheet"> <title></title> </head> <body> <divid="app"> <inputtype="text"v-model="word"@keyup="get"> <ul> <liv-for="keyWordinkeyWords">{{keyWord}}</li> </ul> <pv-show="keyWords.length==0">暂无数据……</p> </div> <scriptsrc="//cdn.bootcss.com/vue/2.0.8/vue.js"></script> <scriptsrc="//cdn.bootcss.com/vue-resource/0.7.2/vue-resource.js"></script> <script> varvm=newVue({ el:'#app',data:{ keyWords:[],word:'' },method:{ get:function(){ this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?',{wd:this.word},{jsonp:'cb'}) .then( function(response){ this.keyWords=response.data.s; },function(response){ alert(response.status) } ) } } }) </script> </body> </html>初步的效果已经出来了
现在增加一个效果,当按下键盘下方向键时,对应的列表项会跟着变色
注意点:
(1)、Vue2.0中获取下标的方式是 (item,index) in items,没有$index
(2)、绑定多个class 的写法,可参照 http://www.jb51.cc/article/p-eefgermb-vt.html
(3)、当到了最后一个列表项时,就把 now设为-1,下次再按下方向键时,就切换到第一个列表项了
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,initial-scale=1"> <linkhref="//cdn.bootcss.com/bootstrap/3.0.1/css/bootstrap.css"rel="stylesheet"> <title></title> <style> .gray{background:#ccc;} </style> </head> <body> <divid="app"> <inputtype="text"v-model="word"@keyup="get"@keydown.down="changeColor"> <ulclass="list-group"> <liv-for="(keyWord,index)inkeyWords":class="['list-group-item',{gray:index==now}]">{{keyWord}}</li> </ul> <pv-show="keyWords.length==0">暂无数据……</p> </div> <scriptsrc="//cdn.bootcss.com/vue/2.0.8/vue.js"></script> <scriptsrc="//cdn.bootcss.com/vue-resource/0.7.2/vue-resource.js"></script> <script> varvm=newVue({ el:'#app',word:'',now:-1,},methods:{ get:function(){ this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?',function(response){ alert(response.status) } ) },changeColor:function(){ this.now++; if(this.now==this.keyWords.length){this.now=-1} } } }) </script> </body> </html>按下方向键,跟着变色
现在想让按上方向键时,也出现变色的功能
(1)、为了阻止index一直减,到了input时 index为-1,所以再往上翻也就是index为-2时,要把index切换到列表项的最后一个列表
(2)、为了阻止按键时,光标跑到了关键字的左边,所以要使用 .prevent 阻止冒泡
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,initial-scale=1"> <linkhref="//cdn.bootcss.com/bootstrap/3.0.1/css/bootstrap.css"rel="stylesheet"> <title></title> <style> .gray{background:#ccc;} </style> </head> <body> <divid="app"> <inputtype="text"v-model="word"@keyup="get"@keydown.down="changeColor"@keydown.up.prevent="changeUpColor"> <ulclass="list-group"> <liv-for="(keyWord,now:-1 },changeColor:function(){ this.now++; if(this.now==this.keyWords.length){this.now=-1} },changeUpColor:function(){ this.now--; if(this.now==-2){this.now=this.keyWords.length-1} } } }) </script> </body> </html>再加一个功能,随着选中不同的列表项,要跟着出现对应的搜索建议
(1)、选中了哪个颜色的列表项,对应的内容就赋值给 word
(2)、在没有任何输入内容的情况下,按上下键时,要跳出循环,不应执行方法,否则会报错
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,methods:{ get:function(event){ if(event.keyCode==38||event.keyCode==40){return}; this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?',changeColor:function(){ this.now++; if(this.now==this.keyWords.length){this.now=-1}; this.word=this.keyWords[this.now]; },changeUpColor:function(){ this.now--; if(this.now==-2){this.now=this.keyWords.length-1}; this.word=this.keyWords[this.now]; } } }) </script> </body> </html>最后再加一个功能,选中了哪个列表项,按回车即打开对应的百度搜索结果
注意:打开的页面url 如下图所示
最终代码:
<!DOCTYPEhtml> <html> <headlang="en"> <Metacharset="UTF-8"> <Metahttp-equiv="X-UA-Compatible"content="IE=edge"> <Metaname="viewport"content="width=device-width,methods:{ get:function(event){ if(event.keyCode==38||event.keyCode==40){return}; if(event.keyCode==13){ window.open('https://www.baidu.com/s?wd='+this.word); this.word=''; } this.$http.jsonp('https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?',changeUpColor:function(){ this.now--; if(this.now==-2){this.now=this.keyWords.length-1}; this.word=this.keyWords[this.now]; } } }) </script> </body> </html>2、如何修改发送给服务端的数据类型
在默认情况下,对于 PUT、POST、PATCH、DELETE等请求,请求头中的 Content-Type 为 application/json,即JSON 类型。有时候我们需要将数据提交为指定类型,如 application/x-www-form-urlencoded、mulitipart/form-data、text/plain等。下面以 POST 请求为例
2-1、全局 headers 配置
Vue.http.headers.post['Content-Type']='application/x-www-form-urlencoded'
2-2、实例配置
this.$http.post( 'http://example.com/books',//成功回调 function(data,status,request){ if(status==200){ console.dir(data); } },{ //配置请求头 headers:{ 'Content-Type':'multipart/form-data' } } )注意:实例配置的优先级高于全局配置,因此最终 Content-Type 为multipart/form-data
@H_202_1403@3、$.http.post 方法变为 OPTIONS 方法
在跨域的情况下,对于非简单请求(PUT、DELETE、Content-Type 为 application/json),浏览器会在真实请求前,额外发起一次类型为 OPTIONS 的请求。只有服务器正确响应了 OPTIONS 请求后,浏览器才会发起真实请求。
因此,为了在跨域的情况下使用 POST 提交 Content-Type 为application/json 的数据或 PUT、DELETE 等非简单请求,首先服务端需要开启 CORS 支持,同时需要设置如下响应头:
Access-Control-Allow-Methods:POST,GET,PUT,DELETE,OPTIONS