跨域请求的三种方案


1.什么是跨域?

指的是浏览器执行不同源的脚本的行为,而在目前的前后端分离的开发工作中跨域访问是不可避免的。
\

2.什么是同源?

指的是 协议、域名、端口 这三者相同 ,浏览器拥有同源策略


例如:http://segmentfault.com/ 这个网址,协议是http://,域名是 segmentfault.com,端口是80。

那么也就是说 https 请求是就是跨域,反过来也是跨域。

如果有的网站可以,那一定是设置了 cors。

3.实现跨域请求的方式有哪些?

3.1 JSONP

script标签设计的时候就允许请求脚本,用这个方法跨域就是jsonp,

3.1.1 步骤

  1. script src 接口 访问
  2. 后端返回 json 数据
  3. 前端执行返回的 JavaScript代码
fucntion bb (data){
    console.log(data);
}
echo "bb('咸鱼翻身,还是咸鱼')";

4.jQuery封装了jsonp

$.ajax({
    type: "get",
    url: "http://localhost:3000/test/JSONP", // 这个就是不同于当前域的一个URL地址,这里单纯演示,所以同域
    dataType: "jsonp",
    jsonpCallback: "JSONPCallback", // 指定回调函数,这里名字可以为其他任意你喜欢的,这里传参callback:JSONPCallback,也可以在下面参数指定键值
    data: {
        name: 'jxq',
        email: 'feichexia@yahoo.com.cn',
    },
    success: function (json) {
        alert(json);
    }
});

3.1.2 前端如何传参

利用url传参,&分割参数,格式如下

接口?key='aabb'

3.1.3 为什么叫jsonp

因为真实数据是json格式,p就是padding填充的意思,指外层包裹着json的函数。

4.返回数据的最后格式是什么样?
json【函数【json真实数据】】

3.1.4 弊端

jsonp是利用script事项,那么只能使用get请求

3.1.4 与CORS区别

默认带cookie,而CORS需要客户端和服务端配置

3.2 CORS

CORS,全称Cross-Origin Resource Sharing ,是一种允许当前域(domain)的资源(比如html/js/web service)被其他域(domain)的脚本请求访问的机制,通常由于同域安全策略(the same-origin security policy)浏览器会禁止这种跨域请求。

3.2.1 步骤

1.同源策略由浏览器产生,当前端跨域请求时,浏览器会在响应头上检查origin判断是否同源。
2.需要后端配置响应头origin

app.all("*", function (req, res, next) {
  //设置允许跨域的域名,*代表允许任意域名跨域
  res.header("Access-Control-Allow-Origin", "*");
  //允许的header类型
  res.header("Access-Control-Allow-Headers", "*");
  //保持跨域时的 Cookie
  res.header("Access-Control-Allow-Credentials", true);
  //跨域允许的请求方式
  res.header("Access-Control-Allow-Methods", "*");
  //字符集类型
  res.header("Content-Type': '*");
  if (req.method.toLowerCase() == 'options')
    res.send(200);  //让options尝试请求快速结束
  //option请求是用于询问所访问的服务器支持什么样的http访问方式。
  //而uniapp访问有两次,一次大概是看看这个服务器是否通的,也就是options请求,
  //这个请求通了,就会发送我们真实请求,如果没通,就不会发送我们的请求。
  else
    next();
});

3.2.2 前端如何传参

前端使用和正常请求无二致,CORS是完全由后端来配置

3.3 服务器代理(正向代理与反向代理)

(1)正向代理

当浏览器访问不了服务端时,可以通过一个代理服务器访问目标服务器。目标服务器接受到代理服务器的请求,将结果返回给代理服务器,
再由代理服务器将结果返回给浏览器,这个过程称之为正向代理。正向代理,目标服务器是不知道真正的访问者是谁的,我们平时见到的科学上网
工具使用的就是正向代理。比如,无法访问google,使用科学上网工具的代理服务器进行间接访问。

(2)反向代理

当浏览器访问www.baidu.com时,背后可能有成千上万的服务器为浏览器服务。浏览器不需要知道背后是哪台服务器为其服务,只需要知道反代理服务器是
www.baidu.com就行。反代理服务器会将浏览器请求转发到真实的服务器。我们常用的Nginx就是性能优异的反向代理服务器,可以用来做负载均衡。

(3)总结

服务对象不同。正向代理的服务对象是浏览器(客户端),而反向代理的服务对象是服务器(服务端)。

浏览器配置不同。正向代理,浏览器需要指明访问的目标服务器,而反向代理,浏览器只关注代理服务器。

(4)反向代理跨域

原理解析:浏览器是禁止跨域的,但是服务端不禁止

在Vue中的应用:vue.config.js可以配置代理服务器

module.exports = {
  devServer: {
    proxy: 'http://localhost:4000'//代理服务器会将请求指向 http://localhost:4000
  }
}

注意:Vue代理基于node服务器,所以只能在开发使用。生产跨域还是乖乖CORS。

https://cli.vuejs.org/zh/config/#devserver-proxy

(5)误区:

Vue跨域配置是正向代理?

我理解正向代理代理的是客户端,并且客户端需要指定目标服务器;
反向代理代理的是服务端,由代理服务器指定目标服务器,客户端无需做任何配置;
Vue中用webpack启动了本地服务器,在这里相当于代理服务器,并在这个代理服务器上配置了目标服务器地址,客户端所有请求都发送到代理服务器上,并且不知道自己的这个请求将会由代理服务器转发到真正服务器上,也就是对客户端来说“代理”这个动作是不可见的,所以属于反向代理。(而在正向代理中客户端必须明确指定自己要代理到哪个目标服务器上)

4. 除了访问限制,浏览器还有什么安全机制

4.1 预检请求(实际上也是同源策略)

请求有简单请求和复杂请求

简单请求:

请求方法是以下三种方法之一:
HEAD
GET
POST
HTTP的请求头信息不超出以下几种字段:
Accept
Accept-Language
Content-Language
Last-Event-ID
Content-Type:只限于三个值application/x-www-form-urlencoded、multipart/form-data、text/plain

https://blog.csdn.net/yexudengzhidao/article/details/124342081


以跨域为前提,当前端自定义header,或是发出危险请求,如put、delete、patch时,浏览会对服务器发出预检请求,请求类型为(option)。
预检请求会判断服务器是否支持当前请求。
需要注意的是简单请求是不会发出预检请求的。
例如,如果清空购物车是个简单请求能做到的事情的话,那同源策略很难帮到你,它只能阻止前端拿到数据,但服务器方法早已执行。毕竟写个img标签也是能让你请求的。
实际的操作都是走token 的模式的
\

5. 为什么只有浏览器有同源策略

知乎回答
纠正,同源策略是针对浏览器没错,但是其它平台想Android也有自己的安全策略,只是它的策略没有体现在api上而已。例如,安卓APP与APP之间的资源不是可以随便访问。

因为,如果用户登录了一个钓鱼的网站,输入账号密码提交,那么钓鱼网站在没有同源策略限制的情况下就能获取一些用户私密信息和进行一些危险操作。

又因为,浏览器向一个域发起请求时总是会带上这个域及其父域的cookies,于是别有用心的人就可以诱骗你进入一个陌生页面,并向一些你可能登录过的网站发请求,盗取你的信息或做一些敏感操作。(注意,这里不是说钓鱼网站获取cookie,而是通过发起请求,请求自动带上cookie。cookie是有域限制的)

浏览器是一个公共空间,存在着很多钓鱼网站,而APP是一个独立的区域,没有这样的问题。


文章作者: iamfugui
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 iamfugui !
评论
  目录