为什么有跨域:
浏览器未来保护用户的安全和隐私给js设置的限制,ajax发送请求,读取响应,浏览器虽然不会阻止你发送请求,但是却读取不到响应
浏览器同源策略:
一个域名的js,在未经允许的情况下,不得读取另一个域名的内容。但是浏览器并不会阻止你发送请求。
- 不同服务器
2. 同一服务器,不同端口
3. 协议不同
form表单为什么可以跨域:
form表单会刷新页面,不会讲结果返回给js所有浏览器认为这是安全的
**
前端解决跨域的方法
**
jsonp:
通过动态的向页面中添加script标签,并且将src设置成请求地址的方式,来实现域请求
jsonp只能实现get请求
原生ajax用jsonp解决跨域:
封装ajax请求:
function ajax(json) {
json.type = json.type ? json.type : 'get';
json.async = json.async == false ? false : true;
json.contentType = json.contentType ? json.contentType : 'application/x-www-form-urlencoded';
json.date = json.date ? json.date : '';
var ajax = new XMLHttpRequest();
// 判断get还是post
if (json.type.toLowerCase() == 'post') {
ajax.open('post', json.url, json.async);
ajax.setRequestHeader('Content-type', json.contentType + ';charset=utf-8');
ajax.send(json.date);
} else {
ajax.open('get', json.url + '?' + json.date, json.async);
ajax.send();
}
ajax.onreadystatechange = function () {
if (ajax.readyState == 4 && ajax.status == 200) {
json.success(ajax.response);
}
}
}
使用:
you.ajax({
'url': './json/index.json',//这里我使用的是自己本地的文件
'dataType': 'jsonp',
'success': function (res) {
var r = JSON.parse(res);
},
'jsonpCallback': 'a'//jsonpCallback用来接收跨域请求的回调函数, 如果没有设置jsonpCallback, 由success的函数来充当回调函数
})
jquery用jsonp:
var url = "https://p.3.cn/prices/mgets?skuIds=J_5089253&type=1";
$.get(url,function(res){
console.log(res)
})
vue中的axios跨域:
- 地址:http://www.axios-js.com
- 含义:易用、简洁且高效的(基于promise)http库 (一个封装好的http插件)
- 特点:
- 支持node端和浏览器端
- 支持promise
- 丰富的配置项
安装:
cnpm/npm install axios -S
页面引入:
import axios from axios
get方法:
axios.get(请求地址,配置对象).then(res=>{ }).catch(err=>{})
//不传参数
axios.get('url')
.then(res=>{
})
.catch(err=>{
})
//传参数 第一种
axios.get('url?id=5&name=张三')
.then(res=>{
})
.catch(err=>{
})
//传参数 第二种
axios.get('url',
{
params:{
参数1:值,
参数2:值
}
})
.then(res=>{
})
.catch(err=>{
})
post方法
axios.post(url, {
参数1: 值,
参数2: 值
})
.then((res) =>{
console.log(response);
})
.catch((error)=> {
console.log(error);
});
axios封装:
src下新建http文件夹,http文件夹下新建index.js用于封装跨域请求和请求拦截及响应拦截,新建api.js用于封装后端接口
config/index.js:
module.exports = {
dev: {
// Paths
assetsSubDirectory: 'static',
assetsPublicPath: '/',
proxyTable: {// 【设置代理!!!】
'/api': { //使用"/地址名"来代替"请求网址"
target: 'http://localhost:3000/', //后端源地址
changeOrigin: true, //改变源
pathRewrite: { // 路径重写
'^/api': '' // 当请求的路径开头有 /地址名 的时候就替换成请求网址
}
}
},
}
http/index.js:
import axios from 'axios'
import router from '../router'
import {Message} from 'element-ui'
const $axios=axios.create({
baseURL:'/api',//使用"/地址名"来代替"请求网址",在config/index.js内
timeout:3000
})
// 请求拦截器 修改请求头 【在请求头上加token】
$axios.interceptors.request.use(function (config) {
// console.log(config)
var token = sessionStorage.getItem('token')
// 修改请求头,每一个请求都会添加token
config.headers.Authorization=token?token:"";
// 请求发送之前做一些事情
return config; //一定要return config 请求无法发送
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 响应拦截器 返回数据的校验 状态是否正确 信息的提取
$axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
// console.log(response)
if(response.data.code == 403){
Message.error(response.data.msg);
router.push('/login')
}
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
export default $axios
http/api.js:
// 存放接口地址
export default{
baseUrl:'http://localhost:3000',
// 菜单管理
menuinfoUrl:'/api/menuinfo',//获取菜单1条
menuaddUrl:'/api/menuadd',//菜单添加
menulistUrl:'/api/menulist',//菜单列表
menueditUrl:'/api/menuedit',//修改
menudeleteUrl:'/api/menudelete',//删除
//角色管理
roleinfoUrl:'/api/roleinfo',//角色菜单1条
roleaddUrl:'/api/roleadd',//角色添加
rolelistUrl:'/api/rolelist',//角色列表
roleeditUrl:'/api/roleedit',//修改
roledeleteUrl:'/api/roledelete',//删除
//管理员管理
userinfoUrl:'/api/userinfo',//获取菜单1条
useraddUrl:'/api/useradd',//菜单添加
userlistUrl:'/api/userlist',//菜单列表
usereditUrl:'/api/useredit',//修改
userdeleteUrl:'/api/userdelete',//删除
usercountUrl:'/api/usercount',//删除
// 用户登录
postuserlogin:'/api/userlogin'
}
vue中使用:
created() {
this.$axios
.get("/api/catelist", {
params: {
istree: 1,
},
})
.then((res) => {
this.first_cates = res.data.list.length;
});
},
react使用axios跨域:
axios封装:
封装步骤和vue一样
使用:
constructor() {
super()
this.state={
bannerarr:[],
}
}
this.$axios.get(this.$api.bannerUrl)
.then(res=>{
// console.log(res.data.banners,"res")
this.setState({
bannerarr:res.data.banners
})
console.log(this.state.bannerarr)
})
render(){
return(<div>
<div className="banner">
<AwesomeSwiper ref={ref => (this.swiperRef = ref)} config={config} className="your-classname banner">
<div className="swiper-wrapper">
{
this.state.bannerarr.map((item,index)=>{
return <div className="swiper-slide" key={index}>
<img src={item.imageUrl} />
</div>
})
}
</div>
{/* <!--左箭头--> */}
<div className="swiper-button-prev"></div>
{/* <!--右箭头--> */}
<div className="swiper-button-next"></div>
<div className="swiper-pagination"></div>
</AwesomeSwiper>
</div>
<div className="main">
</div>
</div>)
}
uni-app跨域网络请求(uni.request):
let baseUrl = null;
if(process.env.NODE_ENV === "development"){
//开发环境
baseUrl="http://localhost:3000"
}else{
baseUrl = "https://api.zhaowei.shop"
}
export default baseUrl;
网络请求
uni.request({
url:"",
data:{},
method:"get",
header:{
"content-type":"application/json"
},
success(res){
}
})
封装
import baseUrl from './config.js'
const http = (options)=>{
return new Promise((resolve,reject)=>{
uni.request({
url:baseUrl + options.url,
data:options.data || {},
method:options.method || "get",
header:options.header || {
"content-type":"application/json"
},
success:resolve,
fail:reject
})
})
}
export default http;
封装api
// 管理所有的api接口
import http from "./http.js"
// 1.获取一级分类
const _getTopCates = () =>{
var options = {
url:"/api/getcate"
}
return http(options)
}
7276




被折叠的 条评论
为什么被折叠?



