前言
域名又称网域、网域名称,是由一串用点分隔的名字组成的Internet上某一台计算机或计算机组的名称,用于在数据传输时标识计算机的电子方位(有时也指地理位置)。internet的核心服务DNS(Domain Name System,网域名称系统,有时也简称为域名)提供域名到IP地址的相映射。以方便用户不用去记机器能识别的IP地址。
域名的划分。我们所熟悉的com,gov,edu,cn,hk,us,tw等等这些是顶级域名,一般用来分配给特殊机构或者某个国家用于标识。在顶级域名下,每个Web网站会到各自国家的域名服务提供商那里去申请域名,申请到的域名就是二级域名,例如:google.com,baidu.com,segmentfault.com等等。在二级域名下,一些大的Web网站一般会根据不同的业务或者功能等,使用不同的子域名即三级域名,例如code.google.com,mail.google.com等等。依此类推,再往下就是三级域名,例如:xxx.xxx.xxx.xxx。一般使用的比较少。说到这,我想你已经可以分辨域名等级了。对于一个url,去掉协议头(例如http://,https://),相对路径(例如/xxx.htm,/xxx/xxx.htm?a=xxx),剩下的部分,看有几个'.',有n个,就是n级域名,没有就是顶级域名。
內域、外域、跨域都是有一个参照物的概念,必须以某个URL为基准,其他的URL对于其而言是属于內域还是外域。对于同一级域名下的所有URL,都属于一个域。
如以mail.google.com/abc/xxx.htm为基准。
內域:mail.google.com/def/xxx.htm与其属于同一个域,故可以认为是內域。
外域:google.com/abc/xxx.htm与其的域名级别不同,不属于同一个域故可认为是外域。
跨域:跨域更多是用来标识某个跳转的动作。如从一个域下面(mail.google.com/abc/xxx.htm)跳转到另一个域下面(google.com/abc/xxx.htm),就可以认为是跨域。所以外域标识的两个URL之间的跳转,就是跨域跳转。
由于浏览器在访问Web网站的时候会与Web服务器建立Seesion(这个做Web开发的应该很清楚了吧,如不太清楚请自行google之),session在浏览器端的保存是通过一个seesionid来维护,而seesionid的作用域是与域名绑定的,不同域名的session是不同的。所以导致了不同域名下的Web站点需要共享某些信息(例如用户的登录信息等)时,就有跨域的问题。通常这是跨域导致的主要问题之一,比较好的解决方案就是SSO。对于跨域还有很多前端的问题:例如JS不能跨域调用等等,由于本人对前端不是十分了解,就不做表述了。
下面是几个简单的跨域例子:
1、一级域名不同:google.com与baidu.com
2、一级域名相同,二级域名不同:mail.google.com与code.google.com
3、依此类推,n级域名相同,n+1级域名不同...
除了这些之外,一般有些人所说的跨域往往还包括:
4、域名相同,端口不同:xxx.com:80与xxx.com:8080 同一个IP不同端口,也是跨域
5、域名相同,协议不同:http://xxx.com与https://xxx.com
6、IP与域名的混合:http://127.0.0.1/和 http://localhost/
前言来自:https://segmentfault.com/q/1010000000151618/a-1020000000151637
为什么会发生跨域问题
1.浏览器限制:
浏览器出于安全的考虑,当浏览器发现跨域时,它会做一些校验,校验不通过时,它就会报错跨域安全问题。
在示例中,(示例见文章尾部)
200:说明请求被正确处理,控制台也打印输出信息。则服务器没有任何问题,而且正确处理,是浏览器报错的原因.
跨域的安全限制都是对浏览器端来说的,服务器端是不存在跨域安全限制的
2.跨域
你发送的请求不属于本域。协议、域名、端口号任何一个不一样,都是跨域。
3.XHR(XMLHttpRequest)请求
<a href="http://localhost:8080/test/getResult">发送请求2</a>
<img src="http://localhost:8080/test/getResult"/>
这两种请求方式都不是XHR请求(1.document,2.json),他们不会报关于跨域安全问题的错。
这三个情况同时满足才会产生跨域安全问题
解决思路
1.浏览器禁止检查
cmd中输入:
2.JSONP解决跨域问题
Jsonp(JSON with Padding) 是 json 的一种"使用模式",是非官方协议,它是一个约定。Jsonp可以让网页从别的域名(网站)那获取资料,即跨域读取数据。jsonp是一个同源策略。端口和主机对于两个页面是相同的,则两个页面具有相同的源,否则就是不同源的。
使用jsonp后台服务器需要修改代码的:
@ControllerAdvice
public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {
public JsonpAdvice() {
// jsonp请求携带一个前后台约定的参数(默认callback,如果写成callback1这类,ajax请求中做以下修改),便于让后台识别是jsonp请求,后台则返回js数据而非json数据
super("callback");
}
}
//后台:super("callback1");时
$.ajax({
url: base + "/getResult",
dataType: "jsonp",
callback:"callback1",
success: function (data) {
result = data;
}
});
刷新后,不再报错。
请求中还有一个参数:_=随机生成的数字,它的作用是防止请求被缓存。如果ajax请求中加上cache:true,这个参数将没有。
请求类型是script
jsonp实现原理:
与原来不同之处:请求类型不同,jsonp的请求类型是script;返回类型也不同,jsonp返回的是js
json核心就是:允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。
Jsonp的弊端
- 服务器需要改动代码支持(如果调用非自己的接口,就无法进行修改了)
- 只支持GET
- 发送的不是XHR请求(ajax的异步就没有了)