现在越来越多的项目就算是一个管理后端也偏向于使用前后端分离的部署方式去做,为了顺应时代的潮流,一前后端分离就产生了跨域问题,所以许多同学把跨域和前后端分离项目联系在了一起,其实跨域产生的原因并不是前后端分离导致的,那我们一起来看一下,希望可以靠这一篇文章解答大家所有的跨域问题

一、跨域产生的条件

  • 使用xmlHttpRequest,即我们通常说的ajax请求
  • 浏览器做了这个事
  • 访问的域名不同,即访问的html页面是a域名下的,但内部js发送的ajax请求的目标地址却是b域名

以上三个条件缺一不可,尤其是第三个条件许多做移动端的同学可能都没有听过,因为移动端爽爽的用各种http请求狂发不同的域名,但是浏览器不允许我们这么做,为了一个词安全

二、如何解决跨域问题

解决跨域问题的根本就是要打破上述的三个限制中的任何一个,我们来看一下逐个击破的方式

JSONP方式

jsonp是打破第一重限制,用了XMLHttpRequest就跨域,那我不用这种方式了,我们怎么做的,来看一段jquery的带jsonp的ajax请求

$.ajax({
type : "GET",
url : "http://api.map.baidu.com/geocoder/v2/",
data:"address=上海",
dataType:"jsonp",
jsonp:"callback",
jsonpCallback:"showLocation",
success : function(data){
alert("成功");
},
error : function(data){
alert("失败");
}
});

看似用了ajax请求,其实内部完全不是那么回事,多了jsonp和jsonpCallback选项,它内部将代码翻译并把页面上的dom操作成这样

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<script type='text/javascript'>
// 后端返回直接执行的方法,相当于执行这个方法,由于后端把返回的数据放在方法的参数里,所以这里能拿到res。
window.showLocation = function (res) {
console.log(res)
//执行ajax回调
}
</script>
<script src='http://api.map.baidu.com/geocoder/v2/?address=上海&callback=showLocation' type='text/javascript'></script>
</body>
</html>

这个时候,html页面的script src标签回去访问api.map.baidu.com的服务端,由于script,img这种标签浏览器是不受xmlhttprequest限制的,可以随意访问,这个时候对应的后端代码取得address参数,最后根据双方约定好的callback参数,返回一个被包装后的json,即

showLocation({
status: 0,
result: {
location: {
lng: 121.4219317908279,
lat: 31.361653367912695
},
precise: 1,
confidence: 80,
comprehension: 99,
level: "道路"
}
})

然后浏览器直接执行了对应的这个showLocation()… 等等,这个不就相当于执行了我们上面定义的window.showLocation方法并且传入了我们需要的json返回吗,那我们的ajax success方法里就可以得到这个返回类型了,并且没有跨域,是不是很精妙。

CORS

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)跨域资源共享 CORS 详解。这个玩样用于“破解”掉浏览器的限制,说是破解其实也是浏览器认识到了一些头部就放行了的意思,需要在http的response内多设置几个头部

  • Access-Control-Allow-Origin:* 表明允许所有的origin(浏览器的html页面路径)访问,而并非是同源的origin
  • Access-Control-Request-Method:* 表明允许所有的http request头,访问,因为浏览器在触发如下几个场景会在发送真正的数据前发送options这样的预检请求检测,一旦预检通过后才会发送真正的get或post数据请求,这个时候我们按照cors的设置就需要允许对应的method访问,触发的几种情况包括
    1:请求的方法不是GET/HEAD/POST
    2:POST请求的Content-Type并非application/x-www-form-urlencoded, multipart/form-data, 或text/plain
    3:请求设置了自定义的header字段等
  • Access-Control-Allow-Headers:* 设置所有header均可以被允许,这个配置联通上述的request method options检测一起使用,可以在需要自定义header的场景下使用
  • Access-Control-Allow-Credentials:true 这个参数只有当需要跨域使用cookie传递时才需要设置为true,并且需要前端ajax配置使用xhrField:{withCredential:true}时才能传递cookie,另外safari和最新版本的chrome浏览器还需要在设置内放开对应限制,可参考我的秒杀课程,当这个参数被设置成true时候Access-Control-Allow-Origin就不能设置为*,否则就变成任何origin域都能允许传递cookie了,可将其调整为前端origin字段传什么我就用什么

若你使用的是nginx反向代理,则可以直接在nginx反向代理上配置

location /{
proxy_pass http://backendserver; add_header Access-Control-Allow-Methods *;
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Headers *; }

代理法

打破不同源的限制,我只要让它同源就可以了,比如要我的静态页面是 http://a.com/index.html 动态ajax请求访问的是http://b.com/api/***

我只需要将对应的服务部署在不同的机器上,然后使用一个公共的c.com的域名作为nginx反向代理的入口域名,在将静态服务和动态服务分别挂在后面的被代理局域网服务器内,修改配置

server{
listen:80;
server_name: c.com; #静态资源
location /{
proxy_pass http://localhost:8080/;
} #ajax动态请求
location /api{
proxy_pass http://localhost:8081/; } }

这样就变成同源了

写在最后

  • 第一:看完点赞,感谢您对作者的认可;
  • ...
  • 第二:随手转发,分享知识,让更多人学习到;
  • ...
  • 第三:记得点关注,每天更新的!!!
  • ...

阿里P7架构师是如何解决跨域问题的!你有遇到吗?的更多相关文章

  1. 转头条:阿里p7架构师:三年经验应该具备什么样的技能?

    问:工作中,有时候实现一个功能,会去看有没有现成的轮子可用.对于重复造轮子与改造轮子有什么看法? 答:一定会的,其实这也是一个提高技术能力的方法,比如今天想做个日期转换的功能,JDK8有日期的新特性就 ...

  2. 阿里P7架构师详解微服务链路追踪原理

    背景介绍 在微服务横行的时代,服务化思维逐渐成为了程序员的基本思维模式,但是,由于绝大部分项目只是一味地增加服务,并没有对其妥善管理,当接口出现问题时,很难从错综复杂的服务调用网络中找到问题根源,从而 ...

  3. 详解阿里P7架构师是怎么在Spring中实现事务暂停

    摘要 Spring框架是一个流行的基于轻量级控制反转容器的Java/J2EE应用框架,尤其在数据访问和事务管理方面的能力是众所周知的.Spring的声明性事务分离可以应用到任何POJO目标对象,并且包 ...

  4. 深入浅出!阿里P7架构师带你分析ArrayList集合源码,建议是先收藏再看!

    ArrayList简介 ArrayList 是 Java 集合框架中比较常用的数据结构了.ArrayList是可以动态增长和缩减的索引序列,内部封装了一个动态再分配的Object[]数组 这里我们可以 ...

  5. 阿里P8架构师深度概述分布式架构

    简介 作为一名架构师,我们要专业,要能看懂代码,及时光着臂膀去机房,也能独挡一面!及时同事搞不定问题,或者撂挑子,你也能给老大一个坚定的眼神:不怕,有我在!还能在会议室上滔滔不绝,如若无人,让不懂技术 ...

  6. 阿里P8架构师谈:数据库分库分表、读写分离的原理实现,使用场景

    本文转载自:阿里P8架构师谈:数据库分库分表.读写分离的原理实现,使用场景 为什么要分库分表和读写分离? 类似淘宝网这样的网站,海量数据的存储和访问成为了系统设计的瓶颈问题,日益增长的业务数据,无疑对 ...

  7. 阿里P8架构师谈:MySQL慢查询优化、索引优化、以及表等优化总结

    更多内容:https://www.toutiao.com/i6599796228886626829/?tt_from=weixin&utm_campaign=client_share& ...

  8. Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战

    转: Java开发不懂Docker,学尽Java也枉然,阿里P8架构师手把手带你玩转Docker实战 Docker简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一 ...

  9. 使用nginx解决跨域问题(flask为例)

    背景 我们单位的架构是在api和js之间架构一个中间层(python编写),以实现后端渲染,登录状态判定,跨域转发api等功能.但是这样一个中间会使前端工程师的工作量乘上两倍,原本js可以直接ajax ...

随机推荐

  1. css样式圆角和一定的透明度

    css样式里可以用border-radius把div或图片变成带有一定圆角的,如果是div本身是正方形,设置圆角度是百分之五十,就是圆形. border-radius:值可以是具体的px数值,也可以是 ...

  2. 【Leetcode_easy】953. Verifying an Alien Dictionary

    problem 953. Verifying an Alien Dictionary solution: class Solution { public: bool isAlienSorted(vec ...

  3. 为nologin用户开一个terminal

    昨天,我在设置zabbix-agent的时候,发现agent机器上的zabbix用户并不能读取某文件信息.我就想跳到zabbix用户,后来失败,发现在/etc/passwd中,zabbix被设置为 z ...

  4. Tomcat中不能通过访问自己IP,但可以通过localhost/127.0.0.1访问

    一.问题如下:局域网内,自己机器部署了一个tomcat应用,在本机上可以通过如下方式访问引用.  http://localhost:8080/xxxx http://127.0.0.1:8080/xx ...

  5. BJFU-208-基于顺序存储结构的图书信息表的最贵图书的查找

    #include<stdio.h> #include<stdlib.h> #define MAX 1000 typedef struct{ double no; char na ...

  6. SAS学习笔记47 Macro Quoting

    简单来说:Macro Quoting就是将具有特殊功能字符及字母组合的特殊功能隐藏掉.例如:让分号(;)不再表示一个语句的结束,而就是一个普普通通的字符:让GE不再表示大于等于的比较符,而就是两个普普 ...

  7. Spring Boot集成Mybatis完整实例

    步骤: 添加Mybatis依赖: 添加数据库依赖: 配置属性文件: (具体的属性名称可以在jar包中找到) 内容: 建表sql: Mapper文件的头: 集成Mybatis的配置文件中的具体内容可以在 ...

  8. C# 小数各种操作

    Math.Ceiling();//向上取整 //举一反三 Math.Floor();//向下取整 Math.Round();//四舍六入五取偶

  9. Pytorch 1.0升级到Pytorch 1.1.0

    Pytorch 1.0Pytorch 1.0于2018-12-8发布,详见https://github.com/pytorch/pytorch/releases/tag/v1.0.0 主要更新JIT全 ...

  10. ASCII&UNICODE编码演化

    ASCII 上个世纪60年代,美国制定了基于拉丁字母的一套电脑编码系统,取名为ASCII.它主要用于显示现代英语和其他西欧语言,是现今最通用的单字节编码系统. ASCII码使用指定的7位或8位二进制数 ...