1.什么是前端跨域?

跨域是浏览器为了安全而做出的限制策略:浏览器请求必须遵从同源测试:
http://www.bilibili.com:8080:/anime/?key=calue路径 键值对
同协议、同域名、同端口

2.ajax和fetch访问接口都会有跨域问题!

3.跨域造成的问题?

a.无法读取非同源网页的cookie、localStorage和indexedDB
b.无法接触非同源网页的DOM
c.无法向非同源地址发送ajax请求

一、CORS跨域-前端最省事(大部分网站不会使用,不安全)

1.概念:CORS是一个W3C标准,全称是"跨域资源共享",允许跨域带入cookid

2.原理:它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制

3.操作:服务端设置,前端直接调用,后台允许前端某个站点进行访问

如图:在”响应请求“里面,只允许http://www.http.com域名进行跨域,*符文是允许所有

// this.$axios.get("http://localhost:5000/students").then((response) => {//   console.log(response);// });//请求会报跨域错误// 解决方法1 cors跨域// this.$axios.get("http://localhost:5000/students").then((response) => {//   console.log(response);// });//在服务器中app.get('/students',(request,response)=>{//response.header("Access-Control-Allow-Origin","*")//后端添加后,可以进行跨域//}//cors跨域// this.$axios.get("https://api.github.com/search/users?q=%E6%88%91").then((response) => {//   console.log(response);// });

后端代码

const express = require('express')
const app = express()app.use((request,response,next)=>{console.log('有人请求服务器1了');// console.log('请求来自于',request.get('Host'));// console.log('请求的地址',request.url);next()
})//修改响应头
app.get('/students',(request,response)=>{response.header("Access-Control-Allow-Origin","*")//后端添加后,可以进行跨域const students = [{id:'001',name:'tom',age:18},{id:'002',name:'jerry',age:19},{id:'003',name:'tony',age:120},]response.send(students)
})app.listen(5000,(err)=>{if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
})

二、jsonp跨域(目前非常流行)

1.原理:最早的解决方案,利用script标签可以跨域的原理实现

在script标签引用了别的源,不会出现跨域问题,设计标签的时候,就允许在别的源请求脚本

HTML5里的script标签默认的type属性是text/javascript,浏览器,就会以js代码来进行执行

2.限制:需要服务的支持、只能发起GET请求

3.优势:

a.在于支持老式浏览器,以及可以向不支持CORS的网站请求数据

b.它不像XMLHttpRequest对象实现的Ajax请求那样受到同源策略的限制,JSONP可以跨越同源策略

4.缺点:

a.它只支持GET请求而不支持POST等其它类型的HTTP请求

b.它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。

c. jsonp在调用失败的时候不会返回各种HTTP状态码

d.缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞,于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta http-equiv="X-UA-Compatible" content="IE=edge"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title>
</head>
<body>
</body>
</html>
<script>
//1.jsonp实现原理-封装写法
function jsonp(req){var script = document.createElement('script');var url = req.url + '?callback=' + req.callback.name;script.src = url;document.getElementsByTagName('head')[0].appendChild(script);
}const students = [{id:'001',name:'tom',age:18},{id:'002',name:'jerry',age:19},{id:'003',name:'tony',age:120},]function hello(res){// alert('hello ' + res);console.log(res)
}// hello(students)
jsonp({url : 'http://localhost:5000/students',callback : hello
});</script><!-- 2.jsonp的原始写法 -->
<!-- <script src="http://localhost:5000/students?callback=hello"></script> -->

后端代码

const express = require('express')
const app = express()app.use((request,response,next)=>{console.log('有人请求服务器1了');// console.log('请求来自于',request.get('Host'));// console.log('请求的地址',request.url);next()
})app.get('/students',(request,response)=>{var funcname = request.query.callback;//获取//console.log('内容',funcname + "(students)");const students = [{id:'001',name:'tom',age:18},{id:'002',name:'jerry',age:19},{id:'003',name:'tony',age:120},]//response.send(funcname + "('你好')")//单个数据//response.send(funcname + '(' + JSON.stringify(students) + ')')//转为json数据-多个数据//fun([{id:'001',name:'tom',age:18},...])//原理是src不受跨域影响,所以让后台返回一个js文件,js里的代码包含数据//response.send(students)
})app.listen(5000,(err)=>{if(!err) console.log('服务器1启动成功了,请求学生信息地址为:http://localhost:5000/students');
})

注意:vue中的“axios默认是没有jsonp 跨域请求的方法的。一般来说流行的做法是将跨域放在后台来解决,也就是后台开发人员添加跨域头信息。
 例如java中的 header,response.setHeader("Access-Control-Allow-Origin", www.allow-domain.com) 也就是CORS跨域
但是很多时候,后台出于一些原因不想修改或者已经写好jsonp的接口需要适应不同平台,此时,前端就可以单独引入依赖解决该问题了

vue安装jsonp跨域:

 npm install jsonp -S

新建一个文件jsonp.js

// 引入原始jsonp插件
import originJsonp from 'jsonp'
/*封装原jsonp插件,返回promise对象url: 请求地址data:请求的json参数option:其他json参数,默认直接写空对象即可
*/
export default function jsonp (url, data, option) {url += (url.indexOf('?') < 0 ? '?' : '&') + param(data)return new Promise((resolve, reject) => {// originJsonp中的参数说明可以到前言中的github中查看originJsonp(url, option, (err, data) => {if (!err) {resolve(data)} else {reject(err)}})})
}
/*封装url参数的拼接*/
function param (data) {let url = ''for (var k in data) {let value = data[k] !== undefined ? data[k] : ''// 防止参数为中文时出现乱码,把字符串作为 URI 组件进行编码url += `&${k}=${encodeURIComponent(value)}`}return url ? url.substring(1) : ''
}

在api文件目录下新建getCurrentCity.js

// 引入封装好的jsonp
import jsonp from '../jsonp'
// 假设这里为跨域请求当前城市的接口
export function getCurrentCity () {// 接口地址let url = 'https://www.imooc.com/carts'// 所需参数let datas = {'qt': 'dec','ie': 'utf-8','oue': 1,'fromproduct': 'jsapi','res': 'api','ak': 'QWilijLzYd6pCmTrHilAeWjbG41zMiXc'}return jsonp(url, datas, {})
}

使用:

// import {getCurrentCity} from './getCurrentCity'//jsonp跨域 引入地址mounted(){this._getCurrentCity ()},methods:{_getCurrentCity (){// getCurrentCity().then((res) => {//引用地址// // 打印出获取到的数据//  console.log(123)//  console.log(res)// }).catch((err) => {//   console.log(err)// })//jsonp跨域},

三、代理跨域-需要建一个vue.config.js-最安全的

1.最安全-最省事-前后端都不需要改,只需要运维团队把配置表改一下,需要服务器部署

2.建一个vue.config.js,文件名是不能改的
3.接口是自己的接口,但是会转接到其他地方
4.node.js是一个后端语言,没有限制,但是不同网站之间存在同源策略限制
5.有个好处在字符串拼接一个空的字符串,可以将请求地址变成一个混淆的地址,这样就最安全的

a.在vue中,新建或者进行修改vue.config.js

module.exports = {pages: {index: {//入口entry: 'src/main.js',},},lintOnSave:false, //关闭语法检查//开启代理服务器(方式一)// devServer: {//   proxy: 'http://localhost:5000'// }, //开启代理服务器(方式二)devServer: {proxy: {'/atguigu': {target: 'http://localhost:5000',pathRewrite:{'^/atguigu':''},//重新路径-正则,匹配所有以atguigu开头的// ws: true, //用于支持websocket// changeOrigin: true //用于控制请求头中的host值},'/demo': {target: 'http://localhost:5001',pathRewrite:{'^/demo':''},// ws: true, //用于支持websocket// changeOrigin: true //用于控制请求头中的host值}}}
}

b.使用

<template></template><script>
export default {name: "Search",data() {return {keyWord: "",};},mounted() {// this.$axios.get("http://localhost:5000/students").then((response) => {//   console.log(response);// });//请求会报跨域错误// 解决方法1 cors跨域// this.$axios.get("http://localhost:5000/students").then((response) => {//   console.log(response);// });//在服务器中app.get('/students',(request,response)=>{//response.header("Access-Control-Allow-Origin","*")//后端添加后,可以进行跨域//}//cors跨域// this.$axios.get("https://api.github.com/search/users?q=%E6%88%91").then((response) => {//   console.log(response);// });//方法二-反向代理this.$axios.get("/atguigu/students").then((response) => {console.log( response.data);//跨域获取成功})this.$axios.get("/demo/cars").then((response) => {console.log( response.data);//跨域获取成功})

c.其他扩张:

module.exports = {devServer:{host:'localhost',//访问主机port:8080,//端口proxy:{//代理-很重要'/api' :{target:'http://mall-pre.springboot.cn',//访问的接口changeOrigin:true,//是否将主机头的原点设置为目标url位置pathRewrite:{//转发地址'/api':''//添加路径的时候,把/api转为空,会把api后面的地址当作真实地址,每个接口都会含/api}},}},// publicPath:'/app',//打包和预览的时候或者,子路径多出一个地址拼接/appoutputDir:'dest',//整个环境打包完之后的输出路径原来是默认是dist   现在是dest文件// indexPath:'index2.html',//单页面的文件名lintOnSave:false, //关闭esli语法检查productionSourceMap:false,chainWebpack:(config)=>{//按需加载config.plugins.delete('prefetch')}}

使用案例:

 this.$axios.get('carts').then((res)=>{this.renderData(res)})

四、其他

1. iframe解决跨域,有四种情况

a.location.hash
b.window.name
c.postMessage
d.document.domain

总结:

General(HTTP)HTTP响应

响应头(response headers)

请求头(request headers)

请求方式
请求地址
请求体

cors跨域方法是自己的服务器端跨域,那肯定可以+header解决
jsonp可以解决别人的服务器的跨域,相当于重新开一个浏览器去请求,然后把响应返回给你

前端交互之“解决前端跨域的三种方法”相关推荐

  1. 什么是同源策略?解决跨域的三种方法?

    1.同源策略 同源策略是一种约定和规范好的安全策略,是浏览器最核心最基本的安全保障.同源政策的目的,是为了保证用户信息的安全,防止恶意的网站窃取数据. 满足的条件: (1)协议要相同:HTTP.HTT ...

  2. $.ajax 加了headers报错_Springboot解决Ajax跨域的三种方式

    这篇文章不华丽,但比较实用,能解决不少大家实际业务中的问题.大家可以收藏起来,以备用时之需! 1.同源策略 1.1 含义 ajax出现请求跨域错误问题,主要原因就是因为浏览器的"同源策略&q ...

  3. 解决前端跨域的几种方法

    解决前端跨域的几种方法 了解跨域出现的原因 解决跨域的几种方法 想要解决跨域 先要知道为什么会出现跨域 跨域:指的是浏览器不能执行其他网站的脚本 它是由浏览器的同源策略造成的 是浏览器对javascr ...

  4. 前端实现跨域的三种方式

    前端解决跨域的三种方式: 1.cors跨域(只需要后端配置) header("Access-Control-Allow-Origin:*"); // 允许任何来源 header(& ...

  5. vue开发环境和生产环境里面解决跨域的几种方法

    vue开发环境和生产环境里面解决跨域的几种方法 参考文章: (1)vue开发环境和生产环境里面解决跨域的几种方法 (2)https://www.cnblogs.com/pass245939319/p/ ...

  6. 什么是同源策略及解决跨域的三种方式

    同源策略 1.1.1 所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个 ip 地址,也非同源.同源策略/SOP(Same origin policy)是一种约 ...

  7. 前端js调用后端API获取数据的三种方法(2022.7.25)

    前端js调用后台API获取数据的三种方法(2022.7.25) 前言 需求分析 一个Get实例 浏览器请求 SoapUI软件请求 一个Post实例 浏览器请求 SoapUI软件请求 1.Http简介( ...

  8. 【Cocos2d-x游戏开发】解决Cocos2d-x中文乱码的三种方法

    [Cocos2d-x游戏开发]解决Cocos2d-x中文乱码的三种方法 参考文章: (1)[Cocos2d-x游戏开发]解决Cocos2d-x中文乱码的三种方法 (2)https://www.cnbl ...

  9. vbs执行ctrl+空格_VBS中解决路径带空格的三种方法

    vbs中,如果需要运行的程序中带有空格,按照通常的方式往往会提示错误,其实有两种形式不同的解决方法: 在应用程序前后分别加三个双引号,代码如下: Set wshell=CreateObject(&qu ...

最新文章

  1. 怎样在bug管理上节省时间
  2. Java实现xml和json互转
  3. plc和pc串口通讯接线_Plc与pc串口调试手册
  4. codeforces 160A-C语言解题报告
  5. s3c6410 jpeg编码 linux,S3C6410 裸机硬件JPEG解码
  6. js调用局部打印功能并还原
  7. Windows命令行优美化:FluentTerminal安装与配置
  8. 优秀课程案例:使用Scratch制作打弹球游戏3-过关增强版
  9. 学习累了吗,来听听乔布斯的演讲吧!
  10. C语言中数据的表现形式及其运算
  11. 【Windows】win7虚拟机安装VMware Tools
  12. java开发的微信公众号服务端生产环境中的两个大坑
  13. CPU指令的流水线执行
  14. 在美国学CS能挣多少钱?美国IT公司标准 offer package详细数字及绿卡政策 | 美国留学申请与就业找工作咨询博客|Warald|一亩三分地论坛...
  15. Android修行手册 - Toolbar实践
  16. lnmp实现搭建商城网站
  17. SpringBoot整合tkMapper
  18. 【论文笔记之 SN-Net】Interactive Speech and Noise Modeling for Speech Enhancement
  19. 前端简单动画组件animation
  20. abp.ajax get,ABP框架中导航菜单的使用及JavaScript API获取菜单的方法

热门文章

  1. 02 Python turtle绘制丘比特爱心
  2. 云原生之kubectl命令详解(二)及pod的相关操作
  3. PyCharm使用Virtualenv和Conda
  4. Macbook键盘无法正常工作怎么办
  5. win10c盘扩容_win10电脑用久了,C盘空间不够用?3步教你无损扩容C盘和分区
  6. Python每日学习-布尔表达式
  7. 【Project】用摄像头测心率
  8. GRS认证标准,GRS再生认证总结
  9. すぬけ君の地下鉄旅行
  10. windows设置共享盘