跨域_2
时间:2023-04-05 20:51:08
HTML5
前端跨域的问题我想很多同学都遇到过,或者刚刚请求数据成功,但是过一会就会报错XMLHttpRequestcannotloadhttp://www.server.com/server....请求的资源上不存在“Access-Control-Allow-Origin”标头。因此不允许访问来源“http://www.client.com”。不知道大家遇到过没有,反正我遇到过。不管什么时候你都有可能遇到跨域什么是跨域?跨域是指一个域下的文档或脚本试图去请求另一个域下的资源。在这里,跨域的定义很广。其实我们通常所说的跨域是狭义的,是一种受浏览器同源策略限制的请求场景。为什么会出现跨域?跨域的主要原因是因为同源策略。什么是同源策略?我们来看看下面的解释。同源策略/SOP(Sameoriginpolicy)是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主域名相同,子域名不同。域名解决方案jsonpJsonp(JSONwithPadding)是json的一种“使用方式”,允许网页从其他域名(网站)获取数据,即跨域读取数据。为什么我们需要一种特殊的技术(JSONP)来访问来自不同域(网站)的数据?这是因为同源策略。同源策略是Netscape提出的一个著名的安全策略,现在所有支持JavaScript的浏览器都在使用。我们已经简单介绍了同源策略。详情请见上文。首先我们先设置script标签,一个简单的jsonp实现,其实就是拼接url,然后在header中动态添加一个script元素。下面看菜鸟教程给的Client例子
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的实现,我们可以像我们设置的token一样设置header的Access-Control-Allow-Origin,设置json格式或者其他格式,当然下面的代码是使用koa-cors插件解决跨域问题varkoa=require('koa');varroute=require('koa-route');varcors=require('koa-cors');varapp=koa();app.use(cors());app.use(route.get('/',function(){this.body={msg:'HelloWorld!'};}));app.listen(3000)其实这一切其实都是cors,那又是什么呢?为什么能解决跨域问题?下面详细了解一下什么是cros:跨域资源共享浏览器将CORS请求分为简单请求(simplerequest)和非简单请求(not-so-simplerequest)两种,这里只说简单请求这里请求方式:请求方式为以下三种方式之一:HEADGETPOSTHTTP头信息不超过以下字段:AcceptAccept-LanguageContent-LanguageLast-Event-IDContent-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文件:{//PathsassetsSubDirectory:'static',assetsPublicPath:'/',proxyTable:{},//各种DevServer设置host:'0.0.0.0',//可以被process.env.HOST覆盖port:8080,//可以被process.env.PORT覆盖,如果端口被占用,则判断为空闲autoOpenBrowser:false,errorOverlay:true,notifyOnErrors:true,poll:false,//https://webpack.js.org/configuration/dev-server/#devserver-watchoptions-..........}以上是我的vueproject中取出来的代码是为了方便大家查找。接下来,我们需要创建一个名为proxy.js的新js文件。配置代码如下:module.exports={proxy:{'/api':{//添加www.qj.com映射/apiUrltarget:'https://www.qj.com',//接口域namesecure:false,//如果是https接口,需要配置该参数changeOrigin:true,//是否跨域pathRewrite:{'^/api':''//路径重写}}}这样我们就可以将proxy.js导入到config文件夹下的index.js中,varproxy=require('./proxy.js'),然后将proxyTable:proxy.proxy插入到我们的dev对象中,实现跨域使用。如果此时我们已经设置完毕,跨域还没有解决怎么办呢?有时我们需要更改我们本地的hosts文件来达到我们解决跨域的目的。其实在我的开发经历中,跨域的东西还是很少的。一般遇到跨域,基本都是在后台处理,之前也会遇到。但是使用jsonp还是比较少见的,上面我们提到的vue-cli的设置解决了跨域的问题。我们看到直接设置webpack就解决了。由于vue开发比较多,所以还是比较关注vue的解决方案,有时候遇到比如我们开发网页和小程序的时候,小程序请求里面没有went,但是web也会造成跨域问题,所以我们只需要设置前台解决跨域问题,或者更稳妥的方式直接让后台一次性解决,以免手机不小心跨域。当然,跨域的解决方案有很多,但这是我遇到并解决的唯一方法。记住参考资料正确面对跨域Domain,别慌菜鸟教程jsonp跨域请求详解-从复杂到简单阮一峰cros