forked from IT-xzy/WEB-NEW
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path1042-js-5.html
357 lines (312 loc) · 16.6 KB
/
1042-js-5.html
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>跨域的几种常见的解决方式</title>
<link rel="stylesheet" href="./css/reveal/reveal.css">
<!-- PPT主题,可以在/css/reveal/theme/中选择其他主题,目前暂时只能使用该模板 -->
<link rel="stylesheet" href="./css/reveal/theme/ptt.css">
<!-- syntax highlighting 代码高亮主题 -->
<link rel="stylesheet" href="./lib/reveal/css/zenburn.css">
<!-- 打印和PDF输出样式 -->
<script>
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = window.location.search.match(/print-pdf/gi) ? './css/reveal/print/pdf.css' : './css/reveal/print/paper.css';
document.getElementsByTagName('head')[0].appendChild(link);
</script>
<style type="text/css">
h3 {
font-family: 'Microsoft Yahei';
}
p {
font-size: 30px !important;
letter-spacing: 2px;
line-height: 50px !important;
text-align: left;
}
B {
color: rgb(195, 255, 219);
font-size: 40px !important;
font-weight: 500 !important;
}
a {
color: #fff !important;
}
</style>
</head>
<body>
<img src="./葡萄藤PPT_files/logo.png" alt="" usemap="#pttmap" class="base-logo">
<map name="pttmap">
<area shape="rect" coords="0,0,276,58" href="http://www.jnshu.com" alt="" target="_blank"/>
</map>
<div class="reveal">
<div class="slides">
<section>
<h2>【JS-task5】</h2>
<h3>跨域的几种常见的解决方式</h3>
<h3>小课堂</h3>
分享人:黄诚翰
</section>
<section>
<p style="text-align: center;">目录</p>
<p style="text-align: center;">1.背景介绍</p>
<p style="text-align: center;">2.知识剖析</p>
<p style="text-align: center;">3.常见问题</p>
<p style="text-align: center;">4.解决方案</p>
<p style="text-align: center;">5.编码实战</p>
<p style="text-align: center;">6.扩展思考</p>
<p style="text-align: center;">7.参考文献</p>
<p style="text-align: center;">8.更多讨论</p>
</section>
<!--1.背景介绍-->
<section>
<section>
<h3>1.背景介绍</h3>
</section>
<section>
<h3>
1.1什么是跨域?
</h3>
<p>
跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
</p>
<p>
广义的跨域:<br>
1.) 资源跳转: A链接、重定向、表单提交<br>
2.) 资源嵌入: link script img frame等dom标签,还有样式中background:url()、@font-face()等文件外链<br>
3.) 脚本请求: js发起的ajax请求、dom和js对象的跨域操作等
</p>
<p>在前端部分其实我们通常所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景。</p>
</section>
<section>
<h3>1.2那么是什么同源策略呢?</h3>
<p>
</p>
</section>
<section>
<p>
同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同,即便两个不同的域名指向同一个ip地址,也非同源。
</p>
<p>
同源策略限制以下几种行为:
1.) Cookie、LocalStorage 和 IndexDB 无法读取
2.) DOM 和 Js对象无法获得
3.) AJAX 请求不能发送
</p>
</section>
<section>
<h3>1.3常见的跨域场景</h3>
<p>
<img src="http://sirengar.club/%E8%B7%A8%E5%9F%9F.jpg">
</p>
</section>
</section>
<!--2.知识剖析-->
<section>
<h3>2.知识剖析</h3>
</section>
<!--2.1 JS有哪些数据类型?-->
<section>
<section><B>2.1 常见的跨域方式</B></section>
<section>
<h4>jsonp</h4>
<p>
在使用XMLHTTPRequest对象发送HTTP请求时,会遇到同源策略问题,域不同请求会被浏览器拦截。这时就可以选择绕过,或者说是不使用XMLHTTPRequest对象进行发送跨域HTTP请求。
在平常写html时会发现比如
<pre>
<code>
<script src="http://www.a.com/script/1.js"></script>
<img src="http://www.b.com/1.jpg">
<link href="http://www.c.com/1.css">
</code>
</pre>
</p>
<p>这种标签是不会遇到'跨域'问题的,严格上来说,这不是跨域,跨域是指在脚本代码中向非同源域发送HTTP请求,这只是跨站资源请求<br>
那么我们可以试试看用这种跨站资源请求的方式来实现跨域HTTP请求
</p>
</section>
<section>
<pre>
<code>
<!-- HTML表头部分-->
...
<!-- javaScript片段1-->
// 如果jsonp 的请求为GET
if ( ctx.method === 'GET' && ctx.url.split('?')[0] === '/getData') {
// 获取jsonp的callback
let callbackName = ctx.query.callback || 'callback'
let returnData = {
success: true,
data: {
text: 'this is a jsonp api',
time: new Date().getTime(),
}
}
// jsonp的script字符串
let jsonpStr = `;${callbackName}(${JSON.stringify(returnData)})`
// 用text/javascript,让请求支持跨域获取
ctx.type = 'text/javascript'
// 输出jsonp字符串
ctx.body = jsonpStr
} else {
ctx.body = 'hello jsonp'
}
})
</code>
</pre>
</section>
<section>
<h3>nginx的反向代理</h3>
<p>nginx支持配置反向代理,通过反向代理实现网站的负载均衡。这部分先写一个nginx的配置,后续需要深入研究nginx的代理模块和负载均衡模块。
nginx通过proxy_pass_http 配置代理站点,upstream实现负载均衡。
</p>
</section>
<section>
<img src="https://images2015.cnblogs.com/blog/305504/201611/305504-20161112125220561-594431822.png">
</section>
<section>
<h3>window.name + iframe</h3>
</section>
<section>
<h3>window.name 传输技术的基本原理: </h3>
<p>当在浏览器中打开一个页面,或者在页面中添加一个iframe时即会创建一个对应的window对象,当页面加载另一个新的页面时,window的name属性是不会变的。这样就可以利用在页面动态添加一个iframe然后src加载数据页面,在数据页面将需要的数据赋值给window.name。然而此时承载iframe的parent页面还是不能直接访问,不在同一域下iframe的name属性,这时只需要将iframe再加载一个与承载页面同域的空白页面,即可对window.name进行数据读取</p>
</section>
<section>
<p>name 在浏览器环境中是一个全局/window对象的属性,且当在 frame 中加载新页面时,name 的属性值依旧保持不变。通过在 iframe 中加载一个资源,该目标页面将设置 frame 的 name 属性。此 name 属性值可被获取到,以访问 Web 服务发送的信息。但 name 属性仅对相同域名的 frame 可访问。这意味着为了访问 name 属性,当远程 Web 服务页面被加载后,必须导航 frame 回到原始域。同源策略依旧防止其他 frame 访问 name 属性。一旦 name 属性获得,销毁 frame 。<br>
在最顶层,name 属性是不安全的,对于所有后续页面,设置在 name 属性中的任何信息都是可获得的。然而 windowName 模块总是在一个 iframe 中加载资源,并且一旦获取到数据,或者当你在最顶层浏览了一个新页面,这个 iframe 将被销毁,所以其他页面永远访问不到 window.name 属性。</p>
</section>
<section>
<pre>
<code>
<script type="text/javascript">
iframe = document.createElement('iframe');
iframe.style.display = 'none';
var state = 0;
iframe.onload = function() {
if(state === 1) {
var data = JSON.parse(iframe.contentWindow.name);
console.log(data);
iframe.contentWindow.document.write('');
iframe.contentWindow.close();
document.body.removeChild(iframe);
} else if(state === 0) {
state = 1;
iframe.contentWindow.location = 'http://localhost:81/cross-domain/proxy.html';//指向自己根目录下的空文件
}
};
iframe.src = 'http://localhost:8080/data.php';//要请求的不同源数据
document.body.appendChild(iframe);
</script>
</code>
</pre>
</section>
<section>
<p>node.js或者其他服务端设置cors表头来授权跨域</p>
</section>
</section>
<!--3.常见问题-->
<section>
<h3>3.常见问题</h3>
</section>
<!--4.解决方案-->
<section>
<h3>4.解决方案</h3>
</section>
<!--5.编码实战-->
<section>
<h3>5.编码实战</h3>
</section>
<!--6.拓展思考-->
<section>
<h3>6.拓展思考</h3>
</section>
<section>
<p>6.1正向代理</p>
<p>正向代理类似一个跳板机,代理访问外部资源。</p>
<img src="https://images2015.cnblogs.com/blog/305504/201611/305504-20161112124853014-1532060796.png">
<p style="font-size: 21px !important"> 我是一个用户,我访问不了某网站,但是我能访问一个代理服务器,这个代理服务器呢,他能访问那个我不能访问的网站,于是我先连上代理服务器,告诉他我需要那个无法访问网站的内容,代理服务器去取回来,然后返回给我。从网站的角度,只在代理服务器来取内容的时候有一次记录,有时候并不知道是用户的请求,也隐藏了用户的资料,这取决于代理告不告诉网站。<br>
客户端必须设置正向代理服务器,当然前提是要知道正向代理服务器的IP地址,还有代理程序的端口。</p>
</section>
<section>
<p>
总结来说:正向代理 是一个位于客户端和原始服务器(origin server)之间的服务器,为了从原始服务器取得内容,客户端向代理发送一个请求并指定目标(原始服务器),然后代理向原始服务器转交请求并将获得的内容返回给客户端。客户端必须要进行一些特别的设置才能使用正向代理。
<br>正向代理的用途:<br>
(1)访问原来无法访问的资源,如google<br>
(2) 可以做缓存,加速访问资源<br>
(3)对客户端访问授权,上网进行认证<br>
(4)代理可以记录用户访问记录(上网行为管理),对外隐藏用户信息
</p>
</section>
<section>
<p>6.2反向代理</p>
<p>客户端是无感知代理的存在的,反向代理对外都是透明的,访问者者并不知道自己访问的是一个代理。因为客户端不需要任何配置就可以访问。<br>
反向代理(Reverse Proxy)实际运行方式是指以代理服务器来接受internet上的连接请求,然后将请求转发给内部网络上的服务器,并将从服务器上得到的结果返回给internet上请求连接的客户端,此时代理服务器对外就表现为一个服务器。<br>
反向代理的作用:<br>
(1)保证内网的安全,可以使用反向代理提供WAF功能,阻止web攻击<br>
大型网站,通常将反向代理作为公网访问地址,Web服务器是内网。</p>
</section>
<section>
<img src="https://images2015.cnblogs.com/blog/305504/201611/305504-20161112124341280-1435223816.png">
<p>(2)负载均衡,通过反向代理服务器来优化网站的负载</p>
<img style="height: 400px" src="https://images2015.cnblogs.com/blog/305504/201611/305504-20161112124423530-566240666.png">
</section>
<section>
<p>6.3二者的区别</p>
<p>借某乎上一个灵魂画手的图片解释下</p>
<img style="height: 600px" src="https://images2015.cnblogs.com/blog/305504/201611/305504-20161112125907030-1432469707.png">
</section>
<section>
<h3>7.参考文献</h3>
前端常见跨域解决方案:https://www.cnblogs.com/roam/p/7520433.html
js中几种使用的跨域方法详解:https://www.cnblogs.com/2050/p/3191744.html
</section>
<section>
<h3>8.更多讨论</h3>
</section>
<section>
<p style="text-align: center">感谢大家观看
<p style="text-align: center">
<small>BY : 黄诚翰</small>
</section>
<script src="./lib/reveal/js/head.min.js"></script>
<script src="./lib/reveal/reveal.js"></script>
</div>
</div>
<script>
// 以下为常见配置属性的默认值
// {
// controls: true, // 是否在右下角展示控制条
// progress: true, // 是否显示演示的进度条
// slideNumber: false, // 是否显示当前幻灯片的页数编号,也可以使用代码slideNumber: 'c / t' ,表示当前页/总页数。
// history: false, // 是否将每个幻灯片改变加入到浏览器的历史记录中去
// keyboard: true, // 是否启用键盘快捷键来导航
// overview: true, // 是否启用幻灯片的概览模式,可使用"Esc"或"o"键来切换概览模式
// center: true, // 是否将幻灯片垂直居中
// touch: true, // 是否在触屏设备上启用触摸滑动切换
// loop: false, // 是否循环演示
// rtl: false, // 是否将演示的方向变成RTL,即从右往左
// fragments: true, // 全局开启和关闭碎片。
// autoSlide: 0, // 两个幻灯片之间自动切换的时间间隔(毫秒),当设置成 0 的时候则禁止自动切换,该值可以被幻灯片上的 ` data-autoslide` 属性覆盖
// transition: 'default', // 切换过渡效果,有none/fade/slide/convex/concave/zoom
// transitionSpeed: 'default', // 过渡速度,default/fast/slow
// mouseWheel: true, //是否启用通过鼠标滚轮来切换幻灯片
// }
// 初始化幻灯片
Reveal.initialize({
history: true,
dependencies: [
{src: './plugin/markdown/marked.js'},
{src: './plugin/markdown/markdown.js'},
{src: './plugin/notes/notes.js', async: true},
{src: './plugin/highlight/highlight.js', async: true, callback: function () {
hljs.initHighlightingOnLoad();
}
}
]
});
</script>
</body>
</html>