跨域:跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,基于同源策略的保护,请求不到数据
同源策略:同协议,同端口,同域名
如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击
跨域解决方案:jsonp , cors (后台) ,反向代理
vue反向代理
如果你是用webpack+cli创建的项目:(如果是cli请往下看)
在config/index.js文件中:
module.exports = {dev: {// PathsassetsSubDirectory: 'static',assetsPublicPath: '/',proxyTable: {"/api": {"target":"http://122.51.36.194:5080",//你要代理的api"changeOrigin":true,"pathRewrite": {"^/api":""//api相当于一个别名}}},//后边的大括号不要忘记
访问时就通过/api
instance.post('/api/......',data).then(res=>{console.log(res)
})
react反向代理
1.配置单个反向代理
在package.json 中添加proxy选项
组件中调用时去掉域名即可
在webpack版本2.0以下,可以是对象(可以设置多个)
在webpack版本2.0以上,只能是字符,只能有一个反向代理
2.配置多个反向代理
安装cnpm i http-proxy-middleware -D
在src文件中新建setupProxy.js文件:
const proxy = require('http-proxy-middleware')module.exports=function(app){app.use(proxy('/ele',{target:'https://h5.ele.me',changeOrigin:true,pathRewrite:{"^/ele":''}})
)
}
请求数据:
import React, { Component } from 'react'
import axios from 'axios'
class Com extends Component {constructor (props) {super(props)this.state = {foods:[]}}componentDidMount(){axios.get('ele/restapi/shopping/v2/entries?latitude=31.378851&longitude=121.491522&templates[]=main_template&templates[]=favourable_template&templates[]=svip_template&terminal=h5').then(res=>{console.log(res.data[0].entries)this.setState({foods:res.data[0].entries})})}render () {return (<div className="box"><header className="header">cart header</header><div className="content"><ul>{this.state.foods.map((item,index)=>(<li key={index}> { item.name }----------{item.activity_id} </li>))}</ul></div></div>)}
}export default Com
vue反向代理
如果你的项目只是用cli创建的:
在根目录下新建vue.config.js文件:
module.exports = {devServer: {proxy: {'/api': {target: 'https://www.daxunxun.com', // 后端接口地址changeOrigin: true, // 是否允许跨越pathRewrite: {'^/api': '' // 重写}},'/ele': {target: 'https://h5.ele.me/', // 后端接口地址changeOrigin: true, // 是否允许跨越pathRewrite: {'^/ele': '' // 重写}}}}
}
请求数据:
mounted () {axios.get('/api/douban').then(res => {console.log(res.data)})}
JSONP
jsonp原理: 利用html标签自带的跨域特点,配合自身引入外部资源的一些属性,在url上拼接回调函数的形式,实现跨域数据的引入
封装jsonp
function jsonp(url,success,data){// 1.解析数据,拼接urldata = data || {};var str = "";for(var i in data){str += `${i}=${data[i]}&`;}var d = new Date();url = url + "?" + str + "__qft=" + d.getTime();// 2.创建script标签var script = document.createElement("script");script.src = url;document.body.appendChild(script);// 3.定义后台要执行的函数window[data[data.columnName]] = function(res){success(res)}}
调用:
document.onclick = function(){var url = "http://localhost/1906/jsonp/data/jsonp4.php";jsonp(url,function(res){res = JSON.parse(res);console.log(res)},{// 后台使用什么样的字段名,接收这个函数名columnName:"cb",// 此键值对,传输的是后台要执行的函数的名字cb:"jasgdjsagd12345678",user:"admin",pass:123});}