摘要:所谓同源是指协议域名端口三者相同,即便两个不同的域名指向同一个地址,也非同源,看看下面的产生跨域的场景你就会明白同源策略的含义。
前端跨域问题我想很多同学遇到过,或者是刚刚请求数据成功, 然而转眼之后就会报错跨域是什么?
XMLHttpRequest cannot load http://www.server.com/server.... No "Access-Control-Allow-Origin" header is present on the requested resource.Origin "http://www.client.com" is therefore not allowed access.
我不知道大家有没有遇到过反正我是遇到过,不管在什么时候你都有可能遇到跨域
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。 其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。为什么会产生跨域?
产生跨域的主要原因是因为同源策略,什么是同源策略呢?我们来看下面的解释
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源,看看下面的产生跨域的场景你就会明白同源策略的含义。
那么有的人会问了,同源策略会产生跨域为什么还要存在呢?平常我们访问网站的时候都是一个地址对应相同的内容,如果同源策略不存在网站的dom很有可能被钓鱼网站复制,那样你就会上当。
那有的人又问了有了同源策略就安全吗?不是有了它就安全是因为同源策略是基础的安全机制,面对强大的攻击还是需要强大的攻防的
url | 说明 | 是否可以通信 |
---|---|---|
http://www.kuayu.com/img.jpg | 同一域名,不同文件,不同路径 | 可以 |
http://www.kuayu.com/img2.jpg | 同一域名,不同文件,不同路径 | 可以 |
url | 说明 | 是否可以通信 |
http://www.kuayu.com:6666/img.jpg | 同一域名,不同端口 | 不可以 |
http://www.kuayu.com/img2.jpg | 同一域名,不同端口 | 不可以 |
url | 说明 | 是否可以通信 |
https://www.kuayu.com/img.jpg | 同一域名,不同协议 | 不可以 |
url | 说明 | 是否可以通信 |
http://www.kuayu.com/img.jpg | 主域相同,子域不同 | 不可以 |
http://kuayu11.com/img2.jpg | 主域相同,子域不同 | 不可以 |
jsonp
Jsonp(JSON with Padding) 是 json 的一种"使用模式",可以让网页从别的域名(网站)那获取资料,即跨域读取数据。
为什么我们从不同的域(网站)访问数据需要一个特殊的技术(JSONP )呢?这是因为同源策略。
同源策略,它是由Netscape提出的一个著名的安全策略,现在所有支持JavaScript
的浏览器都会使用这个策略。同源策略上面咱们已经简单的价绍过了,详细请看上面
首先我们先设置script标签,一个简单的jsonp实现,其实就是拼接url,然后将动态添加一个script元素到头部,我来看下面菜鸟教程给与的客户端例子
JSONP 实例 // 使用函数
我们再来封装一下简单的jsonp函数完整的代码如下面
后台解决跨域JSONP 实例 上面的代码使用方式和咱们菜鸟教程生成的方式是一样的
一般有两种解决方法 1.后台返回的数据格式改成jsonp的形式 2.后台response添加header,response.setHeader("Access-Control-Allow-Origin", "*"); "Access-Control-Allow-Origin", "*" 表示所有网站都可以访问 或者可以指定某个具体域名访问response.setHeader("Access-Control-Allow-Origin", "url")
我们来看看后台代码node + koa 的实现,我们可以通过设置header的Access-Control-Allow-Origin就像是我们设置的token,设置的json格式或是其它格式啊,当然下面的代码是通过使用koa-cors插件进行的解决跨域问题。
var koa = require("koa"); var route = require("koa-route"); var cors = require("koa-cors"); var app = koa(); app.use(cors()); app.use(route.get("/", function() { this.body = { msg: "Hello World!" }; })); app.listen(3000)
其实这一切都归根揭底为cors,那么它是什么呢?它为什么可以解决跨域的问题呢?那我们具体来看看它到底是什么
cros:跨域资源共享 浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple请求方法是以下三种方法之一:
request),咱们在这里只说一下简单的请求方式:
HEAD GET POSTHTTP的头信息不超出以下几种字段:
Accept Accept-Language Content-Language Last-Event-ID Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plainAccess-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin字段的值,要么是一个*,表示接受任意域名的请求。Access-Control-Allow-Credentials
值是一个布尔值,表示是否允许发送Cookie。默认情况下,Cookie不包括在CORS请求之中。设为true,即表示服务器明确许可,Cookie可以包含在请求中,一起发给服务器。这个值也只能设为true,如果服务器不要浏览器发送Cookie,删除该字段即可vue解决跨域方案
我们可以在vue-cli配置文件里面设置一个代理,跨域的方法有很多,通常需要后台来进行配置。
我们可以直接通过node.js代理服务器来实现跨域请求。
接下来我们可以通过vue项目中config文件夹下的index.js配置文件
dev: { // Paths assetsSubDirectory: "static", assetsPublicPath: "/", proxyTable: {}, // Various Dev Server settings host: "0.0.0.0", // can be overwritten by process.env.HOST port: 8080, // can be overwritten by process.env.PORT, if port is in use, a free one will be determined autoOpenBrowser: false, errorOverlay: true, notifyOnErrors: true, poll: false, // https://webpack.js.org/configuration/dev-server/#devserver-watchoptions- ....... ... }
上面是我从vue项目中拿出来的代码供大家便于寻找,接下来我们需要新建一个js文件,名为proxy.js配置代码如下:
module.exports = { proxy: { "/api": { //将www.qj.com映射/apiUrl target: "https://www.qj.com", // 接口域名 secure: false, // 如果是https接口,需要配置这个参数 changeOrigin: true, //是否跨域 pathRewrite: { "^/api": "" //路径重写 } } } }
这把我们需要把proxy.js引入到config文件夹下的index.js中,var proxy = require("./proxy.js"), 然后将proxyTable: proxy.proxy插入到我们的dev对象中进行跨域的使用,我们这时候如果设置完了,跨域还是没有解决怎么办,有时候还得需要更改咱们本地的hosts文件以达到我们解决跨域的目的
总结其实在我开发的经历中遇到跨域的事情还是较少的,一般遇到跨域的时候,基本上都是又后台来处理,以前也会遇到但是使用jsonp的时候还是比较少的,以及上面我们提到的vue-cli的设置解决跨域的问题,我们看到是直接设置webpack的方式来解决,由于vue开发比较多,所以还是比较关注vue的解决方法,有的时候还碰到过比如我们开发web页面和小程序,在小程序请求都没有went,但是到web也会造成跨域问题,所以我们只需设置前台解决跨域问题就行,或者更安全的方式直接让后台一次性解决也免得不小心手机端也跨域了呢。
当然还有很多跨域的解决办法,但是本人遇到与解决的只有这记住方法
参考资料
正确面对跨域,别慌
菜鸟教程
jsonp跨域请求详解——从繁至简
阮一峰cros
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/104531.html
摘要:关于,强烈推荐阅读跨域资源共享详解阮一峰另外,这里也整理了一个实现原理图简化版如何判断是否是简单请求浏览器将请求分成两类简单请求和非简单请求。 前言 从刚接触前端开发起,跨域这个词就一直以很高的频率在身边重复出现,一直到现在,已经调试过N个跨域相关的问题了,16年时也整理过一篇相关文章,但是感觉还是差了点什么,于是现在重新梳理了一下。 个人见识有限,如有差错,请多多见谅,欢迎提出iss...
摘要:同源策略所谓同源是指协议,域名,端口均相同。同源策略是浏览器的一个安全功能,不同源的客户端脚本在没有明确授权的情况下,不能读写对方资源。需注意的是由于同源策略的限制,所读取的为跨域请求接口所在域的,而非当前页。 一、什么是跨域 1.URL解析 URL (Uniform Resource Locator )统一资源定位符(URL)是用于完整地描述Internet上网页和其他资源的地址的...
摘要:学习建议在学习其中一种跨域方法的时候,建议边运行项目里的,边在网上搜索博客文章学习这种跨域方法,这样有助于快速并且深入理解跨域。鉴于网上有很多文章详细讲述跨域知识,只是少了可以本地运行的,所以这里就不再赘述跨域知识。 前言 因为学习跨域需要配置本地服务器,可能会比较麻烦,所以自己根据网上的博客写了大多数跨域的简单demo,可以自己在本地运行,而且不用配置服务器。自己对于跨域的理解刚开始...
摘要:学习建议在学习其中一种跨域方法的时候,建议边运行项目里的,边在网上搜索博客文章学习这种跨域方法,这样有助于快速并且深入理解跨域。鉴于网上有很多文章详细讲述跨域知识,只是少了可以本地运行的,所以这里就不再赘述跨域知识。 前言 因为学习跨域需要配置本地服务器,可能会比较麻烦,所以自己根据网上的博客写了大多数跨域的简单demo,可以自己在本地运行,而且不用配置服务器。自己对于跨域的理解刚开始...
摘要:学习建议在学习其中一种跨域方法的时候,建议边运行项目里的,边在网上搜索博客文章学习这种跨域方法,这样有助于快速并且深入理解跨域。鉴于网上有很多文章详细讲述跨域知识,只是少了可以本地运行的,所以这里就不再赘述跨域知识。 前言 因为学习跨域需要配置本地服务器,可能会比较麻烦,所以自己根据网上的博客写了大多数跨域的简单demo,可以自己在本地运行,而且不用配置服务器。自己对于跨域的理解刚开始...
摘要:实现跨域的原理通过方式请求载入并执行一个文件,相当于通过的形式的导入一个外部的方法语法该函数是简写的函数,等价于在中,您可以通过使用形式的回调函数来加载其他网域的数据,如。将自动替换为正确的函数名,以执行回调函数。 更多详情见http://blog.zhangbing.club/Ja... 最近在项目开发的过程中遇到一些Javascript 跨域请求的问题,今天抽空对其进行总结一下,以...
阅读 1612·2021-10-09 09:44
阅读 2702·2021-10-08 10:04
阅读 2438·2021-09-26 09:55
阅读 3789·2021-09-22 10:02
阅读 3259·2019-08-29 17:08
阅读 1045·2019-08-29 15:08
阅读 2932·2019-08-26 13:52
阅读 3253·2019-08-26 13:34