目录
referer、prototype、array、json笔记整理: http://t.csdn.cn/s4P8x
虚拟主机3种方式nginx/apache+跨域知识点整理
一、Apache基于多IP、多端口、多域名访问
1、添加网卡三种方法
1、虚拟机添加网络适配器
2、命令添加
设置两个端口
1.nmcli connection add con-name ens37 ifname ens37 type ethernet
2.nmcli connection add con-name ens38 ifname ens38 type ethernet
配地址
1.nmcli connection modify ens37 ipv4.addresses 192.168.137.136/24 ipv4.dns 192.168.137.2 ipv4.gateway 192.168.137.2 ipv4.method manual autoconnect yes
2.nmcli connection modify ens38 ipv4.addresses 192.168.137.137/24 ipv4.dns 192.168.137.2 ipv4.gateway 192.168.137.2 ipv4.method manual autoconnect yes
up一下网卡
nmcli connection up ens37/38
3、用nmtui 添加ip地址
输入nmtui进入会话
在Add后面添加IP,然后一直回车
2、添加配置文件、本地域名解析
添加配置文件
cd /etc/httpd/conf.d
添加配置文件,可以去主配置文件/etc/httpd/conf/httpd.conf复制粘贴
# 131
<VirtualHost 192.168.137.131>
DocumentRoot /var/www/html/131
ServerName 192.168.137.131
</VirtualHost>
# 136
<VirtualHost 192.168.137.136>
DocumentRoot /var/www/html/136
ServerName 192.168.137.136
</VirtualHost>
# 137
<VirtualHost 192.168.137.137>
DocumentRoot /var/www/html/137
ServerName 192.168.137.137
</VirtualHost>
# port:100
Listen 100
<VirtualHost 192.168.137.131:100>
DocumentRoot /var/www/html/100
ServerName 192.168.137.131
</VirtualHost>
# port:200
Listen 200
<VirtualHost 192.168.137.131:200>
DocumentRoot /var/www/html/200
ServerName 192.168.137.131
</VirtualHost>
# www.xixi.com
<VirtualHost www.xixi.com>
DocumentRoot /var/www/html/xixi
ServerName www.xixi.com
</VirtualHost>
# www.haha.com
<VirtualHost www.haha.com>
DocumentRoot /var/www/html/haha
ServerName www.haha.com
</VirtualHost>
<Directory "/var/www/html">
AllowOverride None
#Allow open access:
Require all granted
</Directory>
本地域名解析
linux本地解析
windows 本地域名解析
3、创建所需目录文件内容
4、关闭防火墙、开启httpd服务
5、curl 测试,浏览器测试
二、nginx基于多IP、多端口、多域名访问
1、添加配置文件
# 131
server {
listen 80;
server_name 192.168.137.131;
location / {
root /usr/local/nginx/html/136;
index index.html;
}
}
# 136
server {
listen 80;
server_name 192.168.137.136;
location / {
root /usr/local/nginx/html/136;
index index.html;
}
}
# 137
server {
listen 80;
server_name 192.168.137.137;
location / {
root /usr/local/nginx/html/137;
index index.html;
}
}
# port:100
server {
listen 100;
server_name 192.168.137.131;
location / {
root /usr/local/nginx/html/100;
index index.html;
}
}
# port:200
server {
listen 200;
server_name 192.168.137.131;
location / {
root /usr/local/nginx/html/200;
index index.html;
}
}
# www.xixi.com
server {
listen 80;
server_name www.xixi.com;
location / {
root /usr/local/nginx/html/xixi;
index index.html;
}
}
# www.haha.com
server {
listen 80;
server_name www.haha.com;
location / {
root /usr/local/nginx/html/haha;
index index.html;
}
}
2、创建所需目录文件内容
3、curl 测试,浏览器测试
二、跨域知识点整理
1、降域
对于主域相同而子域不同的情况下,可以通过设置 document.domain 的办法来解决。
#master
<iframe id="iFrame" src="http://slave.security.com"></iframe>
<script>
document.domain = 'security.com';
let ifr = document.getElementById('iFrame'); //通过id抓取iframe
ifr.onload = function () {
let win = ifr.contentWindow;
console.info(win);
alert(win.data);
}
</script>
contentWindow 属性返回当前 HTMLIFrameElement 的 Window 对象。 你可以使用这个 Window 对象去访问这个 iframe 的文档和它内部的 DOM.
#slave
<script>
document.domain = 'security.com';
window.data = 'data:111';
</script>
2、hash
在url中,file:///D:/security/phpstudy_pro/WWW/iframe/1.html#12345的#12345
就是location.hash,改变hash值不会导致页面刷新,所以可以利用hash值来进行数据的传递,当然数据量是有限的。
#cs1
<script>
// http://localhost:8080/cs1.html
let ifr = document.createElement('iframe');
ifr.style.display = 'none';
ifr.src = "http://localhost:8081/cs2.html#data";
document.body.appendChild(ifr);
function checkHash() {
try {
let data = location.hash ? location.hash.substring(1) : ' ';
console.log('获得到的数据是:', data);
}catch(e) {
}
}
window.addEventListener('hashchange', function(e) {
console.log('获得的数据是:', location.hash.substring(1));
});
</script>
#cs2
</head>
<body>
<script>
// http://locahost:8081/cs2.html
switch(location.hash) {
case "#data":
callback();
break;
}
function callback() {
const data = "some number: 1111"
try {
parent.location.hash = data;
}catch(e) {
// ie, chrome 下的安全机制无法修改 parent.location.hash
// 所以要利用一个中间的代理 iframe
var ifrproxy = document.createElement('iframe');
ifrproxy.style.display = 'none';
ifrproxy.src = 'http://localhost:8080/cs3.html#' + data; // 该文件在请求域名的域下
document.body.appendChild(ifrproxy);
}
}
</script>
</body>
</html>
#cs3
<script>
parent.parent.location.hash = self.location.hash.substring(1)
</script>
3、window.name
window.name(一般在js代码里出现)的值不是一个普通的全局变量,而是当前窗口的名字,要注意的是每个iframe都有包裹它的window,而这个window是top window的子窗口,而它自然也有window.name的属性,window.name属性的神奇之处在于name值在不同的页面(甚至不同域名)加载后依旧存在(如果没有修改则值不会变化),并且可以支持非常长的name值
举个简单的例子:你在某个页面的控制台输入:
window.name = "hello world"
window.location = "http://www.baidu.com"
页面跳转到了百度首页,但是window.name却被保存下来了,还是hello world。
4、postMessage
postMessage 是 HTML5 新增加的一项功能,跨文档消息传输(Cross Document Messaging),目前:Chrome 2.0+、Internet Explorer 8.0+, Firefox 3.0+, Opera 9.6+, 和 Safari 4.0+ 都支持这项功能。
首先创建 a.html 文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>a.html</title>
</head>
<body>
<iframe src="http://localhost:8081/b.html" style='display: none;'></iframe>
<script>
window.onload = function() {
let targetOrigin = 'http://localhost:8081';
//想要操作当前iframe的时候,就像该ifranme中postMessage()一个东西。
window.frames[0].postMessage('我要给你发消息了!', targetOrigin);
//*表示任何域都可以监听。
}
//当我监听到message事件的时候,我就知道有人向我发送数据了,我获得了数据就可以做对应的事情。内部对消息做实现
window.addEventListener('message', function(e) {
console.log('a.html 接收到的消息:', e.data);
});
</script>
</body>
</html>
创建一个 iframe,使用 iframe 的一个方法 postMessage 可以向http://localhost:8081/b.html
发送消息,然后监听 message,可以获得其他文档发来的消息。
同样的 b.html 文件:
<script>
window.addEventListener('message', function(e) {
if(e.source != window.parent) {
return;
}
let data = e.data;
console.log('b.html 接收到的消息:', data);
parent.postMessage('我已经接收到消息了!', e.origin);
})
</script>
5、jsonp 直接淘汰
1.优点
1.1 JSONP可以跨越同源策略;
1.2它的兼容性更好,在更加古老的浏览器中都可以运行,不需要XMLHttpRequest或ActiveX的支持
1.3在请求完毕后可以通过调用callback的方式回传结果。将回调方法的权限给了调用方。这个就相当于将controller层和view层终于分开了。我提供的jsonp服务只提供纯服务的数据,至于提供服务以 后的页面渲染和后续view操作都由调用者来自己定义就好了。如果有两个页面需要渲染同一份数据,你们只需要有不同的渲染逻辑就可以了,逻辑都可以使用同 一个jsonp服务。
2.缺点
2.1它只支持GET请求而不支持POST等其它类型的HTTP请求
2.2它只支持跨域HTTP请求这种情况,不能解决不同域的两个页面之间如何进行JavaScript调用的问题。
2.3 jsonp在调用失败的时候不会返回各种HTTP状态码。
2.4缺点是安全性。万一假如提供jsonp的服务存在页面注入漏洞,即它返回的javascript的内容被人控制的。那么结果是什么?所有调用这个 jsonp的网站都会存在漏洞。于是无法把危险控制在一个域名下…所以在使用jsonp的时候必须要保证使用的jsonp服务必须是安全可信的。
6、websocket
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 才没有实行同源政策。因为服务器可以根据这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出如下回应。
HTTP/1.1 101 Switching Protocols
Upgrade: websocket
Connection: Upgrade
Sec-WebSocket-Accept: HSmrc0sMlYUkAGmm5OPpG2HaGWk=
Sec-WebSocket-Protocol: chat
7、cors *
CORS 是跨源资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。相比 JSONP 只能发GET
请求,CORS 允许任何类型的请求。
整个 CORS 通信过程,都是浏览器自动完成,不需要用户参与。浏览器一旦发现 AJAX 请求跨域,就会自动添加一些附加的头信息,有时还会多出一次附加的请求,但用户不会有感知。因此,实现 CORS 通信的关键是服务器。只要服务器实现了 CORS 接口,就可以跨域通信。
1、两种请求
CORS 请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)。
只要同时满足以下两大条件,就属于简单请求。
(1)请求方法是以下三种方法之一。
- HEAD
- GET
- POST
(2)HTTP 的头信息不超出以下几种字段。
- Accept
- Accept-Language
- Content-Language
- Last-Event-ID
- Content-Type:只限于三个值
application/x-www-form-urlencoded
、multipart/form-data
、text/plain
凡是不同时满足上面两个条件,就属于非简单请求。一句话,简单请求就是简单的 HTTP 方法与简单的 HTTP 头信息的结合
如果Origin
指定的源,不在许可范围内,服务器会返回一个正常的 HTTP 回应。浏览器发现,这个回应的头信息没有包含Access-Control-Allow-Origin
字段(详见下文),就知道出错了,从而抛出一个错误,被XMLHttpRequest
的onerror
回调函数捕获。注意,这种错误无法通过状态码识别,因为 HTTP 回应的状态码有可能是200。
如果Origin
指定的域名在许可范围内,服务器返回的响应,会多出几个头信息字段。
Access-Control-Allow-Origin: http://api.bob.com
Access-Control-Allow-Credentials: true
Access-Control-Expose-Headers: FooBar
Content-Type: text/html; charset=utf-8
上面的头信息之中,有三个与 CORS 请求相关的字段,都以Access-Control-
开头。
(1)Access-Control-Allow-Origin
该字段是必须的。它的值要么是请求时Origin
字段的值,要么是一个*
,表示接受任意域名的请求。
(2)Access-Control-Allow-Credentials
该字段可选。它的值是一个布尔值,表示是否允许发送 Cookie。默认情况下,Cookie 不包括在 CORS 请求之中。设为true
,即表示服务器明确许可,浏览器可以把 Cookie 包含在请求中,一起发给服务器。这个值也只能设为true
,如果服务器不要浏览器发送 Cookie,不发送该字段即可。
(3)Access-Control-Expose-Headers
该字段可选。CORS 请求时,XMLHttpRequest
对象的getResponseHeader()
方法只能拿到6个服务器返回的基本字段:Cache-Control
、Content-Language
、Content-Type
、Expires
、Last-Modified
、Pragma
。如果想拿到其他字段,就必须在Access-Control-Expose-Headers
里面指定。上面的例子指定,getResponseHeader('FooBar')
可以返回FooBar
字段的值。
2、与 JSONP 的比较
CORS 与 JSONP 的使用目的相同,但是比 JSONP 更强大。JSONP 只支持GET
请求,CORS 支持所有类型的 HTTP 请求。JSONP 的优势在于支持老式浏览器,以及可以向不支持 CORS 的网站请求数据。