一, vue 发送 Ajax 请求
之前我们发送 Ajax 请求的方式, 一是原生的方式发送, 二是通过 jQuery 来发送 Ajax 请求.
但是我们知道, 在 Vue 里面是不推荐使用 jQuery 的, 那么如何使用 Vue 来发送 Ajax 请求呢?
在 Vue 中可以使用第三方插件 vue-resource 来实现 Ajax 请求的发送.
1,vue-resource 安装
1, 通过 npm 的方式在线安装: npm install vue-resource
2, 在 github 中下载 vue-resource 的 文件 (在 dist 文件夹下有个 vue-resource.js 文件.)
3, 使用 CDN.<script src="https://cdn.jsdelivr.net/npm/vue-resource@1.5.1"></script>
2,vue-resource 使用
参考链接: https://github.com/pagekit/vue-resource/blob/develop/docs/http.md
步骤:
1, 在 vue.js 之后引入 vue-resource.js 文件 (因为 vue-resource.js 文件是依赖于 Vue 的)
2, 全局使用:
then 后面第一个参数是请求成功的回调函数; 第二个参数是请求失败的回调函数.
获取到的结果在回调函数的参数中.
- Vue.http.get('/someUrl', [config]).then(successCallback, errorCallback);
- Vue.http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);
- Vue.http.jsonp('/someUrl', [config]).then(successCallback, errorCallback);
3, 局部使用: 在 methods 的事件中, 使用 this.$http.get/post/jsonp(); 的形式发起请求.
- this.$http.get('/someUrl', [config]).then(successCallback, errorCallback);
- this.$http.post('/someUrl', [body], [config]).then(successCallback, errorCallback);
- this.$http.jsonp('/someUrl', [config]).then(successCallback, errorCallback);
示例: 通过三个按钮点击分别获取 get,post,jsonp 请求.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Document</title>
- <script src="./lib/vue-2.4.0.js"></script>
- <script src="./lib/vue-resource-1.3.4.js"></script>
- </head>
- <body>
- <div id="box">
- <input type="button" value="get 请求" @click="getClick">
- <input type="button" value="post 请求" @click="postClick">
- <input type="button" value="jsonp 请求" @click="jsonpClick">
- </div>
- <script>
- var vm = new Vue({
- el: "#box",
- data: {},
- methods: {
- getClick() {
- // 参数 1: 测试用的地址: http://vue.studyit.io/api/getlunbo
- // 参数 2:[config] 可选
- this.$http.get("http://vue.studyit.io/api/getlunbo").then(result => {
- console.log("ok");
- console.log(result.body);
- });
- },
- postClick() {
- // 参数 1: 测试用的地址: http://vue.studyit.io/api/getlunbo
- // 参数 2:[data] 数据, 可为 Object,FormData,String, 这里为空
- // 参数 3:[config] 可选, 但是 emulateJSON = "true" 表名表单格式为: application/x-www-form-urlencoded, 否则
- // 可能有的浏览器不认识.
- this.$http.post("http://vue.studyit.io/api/post", "", {
- emulateJSON: true
- }).then(result => {
- console.log(result.body);
- });
- },
- jsonpClick() {
- this.$http.jsonp("http://vue.studyit.io/api/getlunbo").then(result => {
- console.log(result.body);
- });
- }
- }
- });
- </script>
- </body>
- </html>
注意: 获取到的数据在成功回调函数参数 data 的中, data 是个对象, 具体需要的数据是 data.body.
二, vue-resource 跨域请求数据
1,jsonp 的实现原理
jsonp 主要是为了解决跨域请求问题的.
我们知道, 由于浏览器的安全性限制, 不允许 AJAX 访问 协议不同, 域名不同, 端口号不同的数据接口, 浏览器认为这种访问不安全.
但是, script 标签 src 属性中的链接却可以访问跨域的 js 脚本, 于是利用这种特性, 我们让服务器不再返回数据, 而是返回一段调用某个函数的 js 代码, 然后在 script 中进行调用, 就实现了跨域.
示例: 使用 JSONP, 添加了一个 script 标签, 标签的 src 指向了另一个域 www.xxx.com 下的 jsonp.js 脚本.
- <!DOCTYPE html>
- <html>
- <head>
- <title>title</title>
- </head>
- <body>
- <script type="text/javascript">
- function jsonphandle(data){
- alert("age:" + data.age + "name:" + data.name);
- }
- </script>
- <script type="text/javascript" src="jquery-1.8.3.min.js">
- </script>
- <script type="text/javascript" src="http://www.xxx.com/jsopn.js"></script>
- </body>
- </html>
要实现跨域, 所以返回的 js 代码应该是一个函数的调用. www.xxx.com 下的 jsonp.js 代码如下:
- jsonphandle({
- "age" : 15,
- "name": "John",
- })
于是, 结果就弹出对话框.
我们再改进一下, 在 script 的 src 中传入的大多是后台文件, 这里以 php 文件为例.
由于我们之前传入 js 文件只是想得到一个函数的调用而已, 那么传入 php 文件怎么获取函数的调用呢?
- <!DOCTYPE html>
- <html>
- <head>
- <title>GoJSONP</title>
- </head>
- <body>
- <script type="text/javascript">
- function jsonphandle(data){
- alert("age:" + data.age + "name:" + data.name);
- }
- </script>
- <script type="text/javascript" src="jquery-1.8.3.min.js">
- </script>
- <script type="text/javascript">
- $(document).ready(function(){
- var url = "http://www.xxx.com/jsonp.php?id=1&callback=jsonphandle";
- var obj = $('<script><\/script>');
- obj.attr("src",url);
- $("body").append(obj);
- });
- </script>
- </body>
- </html>
这里动态的添加了一个 script 标签, src 指向跨域的一个 php 脚本, 并且将上面的 js 函数名作为 callback 参数传入, 那么我们看下 PHP 代码怎么写的:
- <?php
- $data = array(
- 'age' => 20,
- 'name' => '张三',
- );
- $callback = $_GET['callback'];
- echo $callback."(".json_encode($data).")";
- return;
php 代码返回的也是一个函数调用, 我们需要的数据, 就在其参数里面. 成功弹出提示框:
- jsonphandle({
- "age" : 15,
- "name": "张三",
- })
最后, jQuery 提供了方便使用 jsonp 的方式:
- <!DOCTYPE html>
- <html>
- <head>
- <title>GoJSONP</title>
- </head>
- <body>
- <script type="text/javascript" src="jquery-1.8.3.min.js">
- </script>
- <script type="text/javascript">
- $(document).ready(function(){
- $.ajax({
- type : "get",
- async: false,
- url : "http://www.xxx.com/jsonp.php?id=1",
- dataType: "jsonp",
- jsonp:"callback", // 请求 php 的参数名
- jsonpCallback: "jsonhandle",// 要执行的回调函数
- success : function(data) {
- alert("age:" + data.age + "name:" + data.name);
- }
- });
- });
- </script>
- </body>
- </html>
其中参数 data, 即为 php 代码返回的函数调用的参数, 就是我们先要的数据.
参考链接: https://blog.csdn.net/u011897301/article/details/52679486
2, 跨域获取电影信息
这里我使用 聚合数据: https://www.juhe.cn 的免费 API.
使用方式很简单, 注册之后, 申请数据后, 在个人中心 -> 我的数据, 接口名称上方查看 key 值.
而我们访问的 url 即为: http://v.juhe.cn/movie/index?key = 您申请的 key&title = 头文字 D
我们在 name 输入框中输入电影名称后, 点击查询按钮即可显示相关信息.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
- <meta http-equiv="X-UA-Compatible" content="ie=edge">
- <title>Document</title>
- <script src="./lib/vue-2.4.0.js"></script>
- <script src="./lib/vue-resource-1.3.4.js"></script>
- <style>
- * {
- padding: 0;
- margin: 0;
- position: relative;
- }
- /* 实现任意无宽高盒子居中 */
- #app {
- width: 100%;
- position: absolute;
- left: 50%;
- /* top: 100px; */
- transform: translateX(-50%);
- }
- .box {
- width: 100%;
- height: 40px;
- background-color: #ccc;
- display: inline-block;
- text-align: center;
- line-height: 40px;
- border: 1px solid #aaa;
- box-sizing: border-box;
- border-bottom: none;
- }
- .box>input[type="button"] {
- width: 60px;
- background-color: #aaa;
- border: 0;
- border: 1px solid #aaa;
- margin: 0 20px;
- }
- .tb {
- width: 100%;
- height: 100%;
- text-align: center;
- border-collapse: collapse;
- border-color: #ccc;
- }
- .th {
- background-color: rgb(24, 204, 204);
- }
- </style>
- </head>
- <body>
- <div id="app">
- <div class="box">
- <label for="name">
电影名:
- <input type="text" id="name" v-model="name">
- </label>
- <input type="button" value="查询" @click="addClick">
- </div>
- <table border="1" cellspacing="0" class="tb">
- <thead class="th">
- <tr>
- <th > 年份 </th>
- <th > 标题 </th>
- <th > 评分 </th>
- <th > 类型 </th>
- <th > 时长 </th>
- <th > 主演 </th>
- <th > 简介 </th>
- <th > 删除 </th>
- </tr>
- </thead>
- <!-- 有查询的话, 这里就不应该固定死, 而是根据 keywords 动态生成新的数组 -->
- <!-- <tr v-for="item in list"></tr> -->
- <tbody>
- <tr v-for="item in list">
- <td>{{item.year}}</td>
- <td>《{{item.title}}》</td>
- <td>{{item.rating}}</td>
- <td>{{item.genres}}</td>
- <td>{{item.runtime}}</td>
- <td>{{item.actors}}</td>
- <td>{{item.plot_simple}}</td>
- <td>
- <!-- 绑定的事件是可以传参数的, 这里传入需要删除的对象 id -->
- <a href="javascript:;" @click.prevent="delClick(item.id)">del</a>
- </td>
- </tr>
- </tbody>
- </table>
- </div>
- <script>
- // 全局配置数据接口的根域名
- //Vue.http.options.root = 'http://v.juhe.cn/';
- var vm = new Vue({
- el: "#app",
- data: {
- name: "",
- rating: "",
- genres: "",
- runtime: "",
- title: "",
- actors: "",
- plot_simple: "",
- year: "",
- // 假数据
- list: [{
- 'rating': 7.3,
- 'genres': '动作 / 惊悚 / 科幻',
- 'runtime': '139 分钟',
- "title": "哥斯拉",
- "actors": "马修. 布罗德里克",
- "plot_simple": "一道亮光划过天际, 太平洋上波涛汹涌",
- "year": "1998",
- },
- {
- 'rating': 1,
- 'genres': 2,
- 'runtime': 3,
- "title": 4,
- "actors": 5,
- "plot_simple": 6,
- "year": 7,
- }
- ]
- },
- methods: {
- // 按钮点击事件处理函数
- addClick() {
- this.getAllList(this.name);
- this.name = "";
- },
- // 获取电影信息
- getAllList(title) {
- // console.log(2);
- title = this.name;
- this.$http.get(`http://v.juhe.cn/movie/index?key=a6c9eddf926517774fe9aa1106ce9295&title=${title}`).then(
- result => {
- if (result.body.result.length == 0) {
- alert("无此电影信息");
- return;
- }
- this.list = result.body.result;
- });
- }
- }
- });
- </script>
- </body>
- </html>
由于 API 要求我们访问的方式为 get 请求, 所以我们使用 this.$http.get 的方式来获取电影信息.
然后打印获取到的数据 result, 但是却爆出如下错误信息:
错误信息是表示, 无法实现跨域. 而我们之前知道 jsonp 是可以实现跨域问题的.
于是我将 get 请求改为 jsonp 请求: this.$http.jsonp 就可以了.
改进:
之前直接把数据接口放在了请求地址里面, 如果地址变了, 就要在请求地址里面修改, 如果不止一个还有其他 post,get 请求等, 那么就要修改多次, 所以我们有必要动态的指定数据接口.
使用: Vue.http.options.root = 'http://v.juhe.cn/'; 来指定数据接口的根地址.
我们在请求的时候只需要写 movie/index?key=a6c9eddf926517774fe9aa1106ce9295&title=${title} 就可以了.
注意: 后续地址, 不要写 / , 否则就不会将根地址和后续地址进行拼接.
当然, 对于我们发给服务器的数据, 可能会需要 emulateJSON = true;
我们也可以进行全局配置: Vue.http.options.emulateJSON = true;
来源: https://www.cnblogs.com/lvonve/p/9656830.html