解决跨域问题的几种方法:

  1. a标签跳转,表单提交;
  2. 资源嵌入 link iframe img iframe script标签
  3. JSONP跨域

跨域请求的是哪些资源

例如说js文件是资源,图片视频属于资源,css 文件等等都属于资源

哪些资源算跨域请求资源

  1. 后端接口的数据

  2. 其他域的cookie

  3. 其他域的缓存

跨域的定义以及跨域发生在哪里

要请求的数据协议,域名,端⼝这三个,有任意⼀个不一样就算跨域。

跨域发生的过程(跨域发生在浏览器)

1. 即使跨域了(协议,域名,端口号有不⼀样的),请求也可以发出。

2. 服务器端也是可以接收的。

3. 服务器端也是可以正常处理理的。

4. 服务器端也是可以正常返回数据。

5. 浏览器也能接收到这些数据。

6. 接收到之后,发现当前⻚面的域和请求的域不不同,所以判定为跨域。

7. 我们的代码在这等着结果呢,但是因为浏览器判定跨域了,不会把结果传递给我们的代码。

解决跨域问题

后端(别⼈家的)配合我们进⾏跨域。

1. JSONP(正常的情况,返回的数据都是JSON格式。JSONP是⼀种特殊的格式。)
2. 后端设置Access-Control-Allow-Origin属性以⽀持跨域。

JSONP跨域的原理

1. 判断请求与当前页面的域是否同源,若同源则发送ajax。
2. 如果不同源则生成一个script标签
3.  生成一个随机的callback名字,还得创建一个名为这个的方法。(因为JSONP格式一定要传回调函数)
  1. 设置script标签的src,设置为要请求的接口。

  2. 将callback作为参数拼接在后面。

  3. 后端接收到请求后,开始准备要返回的数据

  4. 后端拼接数据,将要返回的数据用callback的值和括号包裹起来

​ 例如:callback=asd123456,要返回的数据为{“a”:1, “b”:2},

​ 就要拼接为:asd123456({“a”:1, “b”:2});

  1. 浏览器接收到内容,会当做js代码来执行。
  2. 从而执行名为asd123456的方法。这样我们就接收到了后端返回给我们的对象。在返回对象的data里面就能访问到JSON格式的数据。

JSONP实现原理

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
var $ = {
ajax: function (options) {
var url = options.url;
var type = options.type;
var dataType = options.dataType;
//判断是否同源(协议,域名,端口号)
var targetProtocol = "";//目标接口的协议
var targetHost = "";//目标接口的host,host是包涵域名和端口的
//如果url不带http,那么访问的一定是相对路径,相对路径一定是同源的。
if (url.indexOf("http://") == 0 || url.indexOf("https://") == 0) {
var targetUrl = new URL(url);
targetProtocol = targetUrl.protocol;
targetHost = targetUrl.host;
} else {
targetProtocol = location.protocol;
targetHost = location.host;
}
//首先判断是否为jsonp,因为不是jsonp不用做其他的判断,直接发送ajax
if (dataType == "jsonp") {
//要看是否同源
if (location.protocol == targetProtocol && location.host == targetHost) {//表示同源
//此处省略。因为同源,jsonp会当做普通的ajax做请求
} else {//不同源,跨域
//随机生成一个callback
var callback = "cb" + Math.floor(Math.random() * 1000000);
//给window上添加一个方法
window[callback] = options.success;
//生成script标签。
var script = document.createElement("script");
if (url.indexOf("?") > 0) {//表示已经有参数了
script.src = url + "&callback=" + callback;
} else {//表示没有参数
script.src = url + "?callback=" + callback;
}
script.id = callback;
document.head.appendChild(script);
}
}
}
}

评论