什么是跨域、怎么解决跨域以及如何实现跨域下的登录

前言:在以往开发中,不会涉及到跨域的问题,因为往往都是在同一个项目中开发代码或者单纯写小demo;However,在实际项目中,前后端分成两个不同的项目,各自部署在不同的域名下,这也就会遇到跨域问题了。

既然问题发生了,那就要从根本上去解决问题,在开始说解决方案前,我们有必要了解一下什么是跨域


1、什么是跨域

浏览器同源策略限制下,向不同不同协议、不同域名或者不同端口)发送XHR请求,浏览器认为该请求不受信任,禁止请求,具体表现为请求后不正常响应

从定义中可以看到这都是浏览器做的“好事”。那么什么是不用源呢?其实也很简单,只要页面的协议、域名和端口与请求地址的没有完全一样,就认为你是不同源,举个极端例子来说:

http://www.baidu.com:80

https://msg.baidu.com:8080


2、怎么解决跨域

只要思想不滑坡,办法总比困难多,既然已经了解什么是跨域,那我们就着手来解决这个问题

1.从浏览器入手

其实跨域只在浏览器下才会触发,那有没有办法禁用浏览器的同源策略呢?办法还真的有。

对于IE浏览器:进入ie的网际网路选项设置,然后选择安全性,再选择自订等级,然后下拉,找到「存取跨网络的资料来源」,选择启用即可;

对于chrome浏览器:通过在命令行,输入chrome.exe --allow-file-access-from-files --user-data-dir="C:/Chrome dev session" --disable-web-security,这会新建一个浏览器实例,自动打开的chrome会显示一系列黄色的文字就说明成功了;

对于FireFox浏览器:在地址栏输入about:config,然后下拉找到security.fileuri.strict_origin_policy,然后设置为false即可

2.从域名入手

既然域名等信息不一致导致跨域产生,那么干脆就把两个项目合并成一个项目,使用相同的协议、域名和端口。

3.从jsonp入手

其实认真想想,我们的系统中经常会用到外链的图片、样式文件以及插件,那这些不会导致跨域吗?是的,真的不会,因为这些是http请求,并不是前面定义的xhr(XmlHttpRequest)请求。

既然图片和js脚本可以正常请求,那么如果把script脚本的src改成我需要跨域请求的url是不是就可以了呢?

是可以的,当请求接口返回的数据需要稍微处理下。在平常引入script脚本时,下载完文件后自动执行,如果我们把src改成跨域url,而且返回值是一段jjs语句,比如:

req.send("alert(1)"); //后台返回js语句

那么前台会会自动解析并执行(这里是弹出1)。那么,如果返回的js语句是一个调用函数的js语句,恰巧前台事先定义了该函数,如:

//前台

function fun(msg){  alert(msg);  }

//后台

req.send("fun('你渴望力量吗')");

那么在fun函数将被调用(可以理解成后台调用前台代码),如果对fun的参数进行处理,就可以实现复杂的业务逻辑了。

在实际情况下是怎么处理的呢?一般我们会先协商好需要被调用的方法及参数(fun),然后动态创建一个script标签,并设置该标签的src为跨域url,最后插入到文档中,插入后,浏览器会自动发起http的get请求,下载完成后将会执行后台返回的js语句(后台调用前台)。

这就是jsonp。

4.从代理入手

还是回到最开始,既然浏览器认为非同源不安全,那么向同源请求不就行了?我们把请求转到同一项目下的后台,在同项目的后台进行xhr请求,然后把请求结果原样返回给前台,这就是代理(或者叫转发)。

成功的原因是同源策略只在浏览器下才起作用,我用后台来请求其他的url,那是不受影响的。开启后台代理可以用C#、JAVA、NodeJs、甚至是python都行,只要能被前端访问的并且能转发请求就可以。

5.从CORS入手

除了前面的几种方法外,还有一种简单得多的方法,那就是后台的请求响应头告诉浏览器“我的这个请求很安全,允许当前域名跨域访问”。如何去实现的呢,其实这是利用了CORS(Cross-Origin Resource Sharing, 跨源资源共享),听起来牛逼哄哄的,其实也就是一个W3C新标准,浏览器检测到响应头的一些字段的值后,跳过同源策略。

那么有那些响应头字段,以及它们分别是什么定义呢?

res.header("Access-Control-Allow-Origin", "*"); //允许全部域名跨域,可以指定特点域名,逗号分隔

  res.header("Access-Control-Allow-Credentials", "true"); //允许携带cookie

  res.header("Access-Control-Allow-Headers", "X-Requested-With"); //允许传输的请求头

  res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS"); //允许发送的xhr模式

  res.header("X-Powered-By", " 3.2.1"); //快速模式

  res.header("Content-Type", "application/json;charset=utf-8"); //类型及字符编码


3、如何实现跨域下的登陆

用前面任意一种方案都可以解决跨域,然而,跨域带来的登陆问题却不好解决。在说如何解决登陆问题前,还是按照老规则说一下问什么就登陆不了了。

在解析前需要先明确几点:

1:http是无状态的,不知道该请求归属于谁

2:每次http请求都会自动携带cookie(在请求头中)

3:session存放在服务端,是有时间有效性的,一段时间内不访问将失效

在正常情况下(非跨域),我们前台发出post请求,携带账号、密码、验证码,提交给后台,后台检查数据后,设置session并返回登陆信息完成登陆,这就是一个简单的登录流程。当用户发起一个新的请求的时候,后台通过请求上下文可以获取到已经保存在服务端的session信息,如:

req.session["UserInfo"] 
//登录时设置了key为UserInfo的session

乍一看就是这么一回事,当时仔细想想又会发现奇怪的地方:

①都说了http是无状态的,在上一个请求设置的session,为什么在下一个请求中可以获取到呢?

②session的key是UserInfo,如果有多个用户同时操作,拿到的值会不会是同一个呢?


接下来我们先介绍一下session的设置与读取

说起session,就不得不说cookie,两者都是缓存,只不过前者保存在服务端,后者保存在客户端。在登录完成后,后台设置一个key为UserInfo的session对象(就叫对象S吧),这个对象S有三个重要的属性,分别是key、value以及sid。key和value的非常好理解,那sid是拿来干嘛?

其实sid又叫session_id,是这个session对象的主键。

众所周知,http是无状态的,为了区分状态,在设置session的时候,服务端会自动在http请求的响应头中把sid设置到cookie中(开发人员感知不到这步操作的,也就是自动设置cookie),浏览器响应请求后,会把更新带有sid的cookie,并在下一个请求时自动带上cookie(浏览器请求自动携带cookie,也是静默操作,关于携带cookie的后面还会继续介绍)。

当第二次请求来到后台,此时已经带上了sid的cookie,如果这时候获取session,服务器将会遍历session列表,匹配所有sid是cookies中的sid的session,再通过key作为索引找到相应的结果。

这就是设置session和读取session的流程,下面是一个简单的图片说明

session



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,635评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,628评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,971评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,986评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,006评论 6 394
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,784评论 1 307
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,475评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,364评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,860评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,008评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,152评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,829评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,490评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,035评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,156评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,428评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,127评论 2 356

推荐阅读更多精彩内容