一、什么是跨域
了解跨域之前先了解同源策略。
同源策略:即浏览器为保障用户的安全,浏览器为了保证用户信息的安全,防止恶意的网站窃取数据,禁止不同域之间的JS进行交互。对于浏览器而言只要域名、协议、端口其中一个不同就会引发同源策略,从而限制他们之间如下的交互行为:
1、Cookie、LocalStorage 和 IndexDB 无法读取;
2、 DOM 无法获得;
3、 AJAX 请求不能发送。
只有协议、域名、端口都相同才是同域,否则就是跨域。
http://www.123.com/index.html 调用 | http://www.123.com/server.php (非跨域) |
http://www.123.com/index.html 调用 | http://www.456.com/server.php (主域名不同:123/456,跨域) |
http://abc.123.com/index.html 调用 | http://def.123.com/server.php (子域名不同:abc/def,跨域) |
http://www.123.com:8080/index.html 调用 | http://www.123.com:8081/server.php (端口不同:8080/8081,跨域) |
http://www.123.com/index.html 调用 | https://www.123.com/server.php (协议不同:http/https,跨域) |
二、如何解决跨域问题?
参考博客:https://blog.csdn.net/Joyhen/article/details/21631833
https://blog.csdn.net/Joyhen/article/details/21631833
(只分析常用的解决方法)
(一)Ajax跨域可以选择:
1、JSONP
原文博客:https://blog.csdn.net/u011897301/article/details/52679486
JSONP由两部分组成,回调函数和数据。JSONP是被包含在函数调用中的JSON,如:callback({"name":"Judy"});
回调函数一般请求中指定,而数据就是传入回调函数中的JSON数据。
它的基本思想是,网页通过添加一个元素,向服务器请求JSON数据,这种做法不受同源政策限制;服务器收到请求后,将数据放在一个指定名字的回调函数里传回来。
(1)什么是JSONP?
首先抛出浏览器同源策略这个概念,为了保证用户访问的安全,现代浏览器使用了同源策略,即不允许访问非同源的页面。JSONP就是用来解决跨域请求问题的。
(2)JSONP原理
ajax请求受同源策略影响,不允许进行跨域请求,而script标签src属性中的链接却可以访问跨域的js脚本,利用这个特性,服务端不再返回JSON格式的数据,而是返回一段调用某个函数的js代码,在src中进行了调用,这样实现了跨域。
2、CORS(跨域源资源共享 Cross-Origin Resource Sharing)(此解决方法更好)
参考阮一峰老师的博客:http://www.ruanyifeng.com/blog/2016/04/cors.html
CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10。
整个CORS通信过程,都是浏览器自动完成,不需要用户参与。对于开发者来说,CORS通信与同源的AJAX通信没有差别,代码完全一样。浏览器一旦发现AJAX请求跨源,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感觉。
因此,实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
(与JSONP比较 :
CORS与JSONP的使用目的相同,但是比JSONP更强大。
JSONP只支持GET
请求,CORS支持所有类型的HTTP请求。JSONP的优势在于支持老式浏览器,以及可以向不支持CORS的网站请求数据。)
3、Web Sockets
WebSocket是一种通信协议,使用ws://
(非加密)和wss://
(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
下面是一个例子,浏览器发出的WebSocket请求的头信息(摘自维基百科)。
GET /chat HTTP/1.1
Host: server.example.com
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Key: x3JJHMbDL1EzLkh9GBhXDw==
Sec-WebSocket-Protocol: chat, superchat
Sec-WebSocket-Version: 13
Origin: http://example.com
上面代码中,有一个字段是Origin
,表示该请求的请求源(origin),即发自哪个域名。
正是因为有了Origin
这个字段,所以WebSocket才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。
(二)主域相同,处理多级子域之间的通信可以选择:
1、document.domain
(三)处理不同域之间的iframe,子窗口可以选择:
1、window.name
2、window.postMessage
3、location.hash
三、页面编码和被请求的资源编码如果不一致如何处理?
即前端请求和后端资源的编码不一致,对于 ajax 请求传递的参数,
如果是 get 请求方式,参数如果传递中文,在有些浏览器会乱码,不同的浏览器对参数编码的处理方式不同,所以对于 get 请求的参数需要使用 encodeURIComponent 函数对参数进行编码处理,后台开发语言都有相应的解码 api。
对于 post 请求不需要进行编码。
四、简述Ajax原理及请求过程
1、创建一个XMLHttpRequest对象,也就是创建一个异步调用对象;
2、创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及验证信息;
3、设置响应HTTP请求状态变化的函数;
4、发送HTTP请求;
5、获取异步调用返回的数据;
6、使用JS和DOM实现局部刷新。