Vue通过axios与java交互,并解决跨域问题

时间:2024-04-09 19:47:41

1. 背景

(1) 弃vue-resource推axios

Vue.js之前是推荐使用的vue-resource,但之后尤雨溪(vue.js作者)发布消息如下:

最近团队讨论了一下,Ajax 本身跟 Vue 并没有什么需要特别整合的地方,使用 fetch polyfill 或是 axios、superagent 等等都可以起到同等的效果,vue-resource 提供的价值和其维护成本相比并不划算,所以决定在不久以后取消对 vue-resource 的官方推荐。已有的用户可以继续使用,但以后不再把 vue-resource 作为官方的 ajax 方案。

这里可以去掉 vue-resource,文档也不必翻译了。

消息原文:https://github.com/vuefe/vuejs.org/issues/186

目前主流的 Vue 项目,都选择 axios 来完成 ajax 请求。

(2) axios简介

npm网站对axios做了很详尽的介绍:
https://www.npmjs.com/package/axios

中文可以参考之前转载的文章《axios全攻略》

axios

Promise based HTTP client for the browser and node.js

Features:
Make XMLHttpRequests from the browser
Make http requests from node.js
Supports the Promise API
Intercept request and response
Transform request and response data
Cancel requests
Automatic transforms for JSON data
Client side support for protecting against XSRF

Browser Support:
Vue通过axios与java交互,并解决跨域问题

2. 实战

关于axios的基本情况就是这样了,那么如何在Vue的工程中进行使用呢?这里给出最简单的实例,axios还有很多高级的用法,在上文推荐的介绍中有详细介绍。

(1) 安装

在工程目录下,使用命令行:

npm install axios --save-dev
  • 1

--save-dev以省掉手动修改package.json文件的步骤。

(2) 改写原型链

在main.js中引如axios。由于在其他组件中无法使用axios命令,所以需要将axios改写为Vue的原型属性。

import axios from 'axios' //引入axios

Vue.prototype.$ajax=axios //修改Vue的原型属性
  • 1
  • 2
  • 3

(3) 在组件中使用

在组件的钩子函数中使用,与后端API交互。

mounted(){

    //GET
    this.$ajax({
      method: 'get',
      // url:'../static/test/getInfo.json', //<---本地地址
      url: '/api/drummer/8bd17859',
    }).then(response=>{
      let _data=response.data;
      alert("hello," + _data.username);
    }).catch(function(err){
        console.log(err)
    })

    //POST
    this.$ajax({
      method: 'post',
      url: '/api/drummer',
      data:{
        code: '1234567',
        username: 'Joyce'
      }
    }).then(response=>{
        alert('post code done');
    }).catch(function(err){
        console.log(err)
    });
  }


3. 解决IE兼容问题

在上文的介绍中,我们提到了浏览器的兼容性。IE9+是可以支持的,但是运行项目后,却发现不可以。为什么呢?

这是因为IE整个家族都不支持promise。如何解决?

(1) 安装es6-promise

npm install es6-proimse --save-dev
  • 1

(2) 引入

main.js中引入ES6的polyfill。

import Es6Promise from 'es6-promise'

Es6Promise.polyfill();
  • 1
  • 2
  • 3
					<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-2011a91181.css" rel="stylesheet">
            </div>
								
				<script>
					(function(){
						function setArticleH(btnReadmore,posi){
							var winH = $(window).height();
							var articleBox = $("div.article_content");
							var artH = articleBox.height();
							if(artH > winH*posi){
								articleBox.css({
									'height':winH*posi+'px',
									'overflow':'hidden'
								})
								btnReadmore.click(function(){
									if(typeof window.localStorage === "object" && typeof window.csdn.anonymousUserLimit === "object"){
										if(!window.csdn.anonymousUserLimit.judgment()){
											window.csdn.anonymousUserLimit.Jumplogin();
											return false;
										}else if(!currentUserName){
											window.csdn.anonymousUserLimit.updata();
										}
									}
									
									articleBox.removeAttr("style");
									$(this).parent().remove();
								})
							}else{
								btnReadmore.parent().remove();
							}
						}
						var btnReadmore = $("#btn-readmore");
						if(btnReadmore.length>0){
							if(currentUserName){
								setArticleH(btnReadmore,3);
							}else{
								setArticleH(btnReadmore,1.2);
							}
						}
					})()
				</script>
				</article>

4. 解决跨域问题

1:服务器端设置跨域

header(“Access-Control-Allow-Origin:*”);

header(“Access-Control-Allow-Headers:content-type”);

header(“Access-Control-Request-Method:GET,POST”);

2:可以自己设置一个代理服务器,使用proxyTable 我比较推荐这种方法。

首先在config/index.js 里面找到proxyTable :{} ,然后在里面加入

 "/api":{
            target: 'http://47.104.218.122:8087',
            changeOrigin: true,
            pathRewrite: {
                '^/api': '/'
            }
        }

注意这里面 /api是你自定义的,写成什么都可以。target 设置你调用的接口域名和端口号。这里理解成用‘^/api’代替target里面的地址,后面组件中我们调接口时直接用api代替 。比如我要调用’http://47.104.218.122:8087/dictionaryType‘,直接写‘/api/dictionaryType’即可。
然后我们可以在main.js设置一个基础路径,这样你调用接口的时候可以不写api,直接写/接口名称即可。在main.js 设置 axios.defaults.baseURL=”/api”;
然后掉接口的时候可以直接写let _url4=”/dictionaryTypes”;这样就比较省事。

    this.$axios.get(_url4)
                    .then(response=>{
                        alert(response);
                        alert(1);
                    })
                    .catch(error=>{
                        console.log(error);
                    })
 这个是我使用vue 的时候遇到的问题   仅作为参考。 
            </div>