浏览器同源策略

100 阅读2分钟

什么是浏览器同源策略?

同源是指"协议+域名+端⼝"三者相同,即便两个不同的域名指向同⼀个ip地址,也⾮同源。

如何实现跨域?

1.jsonp

优点:实现简单、兼容性⾮常好

缺点:只⽀持get请求(因为 script 标签只能get)

有安全性问题,容易遭受xss攻击

需要服务端配合jsonp进⾏⼀定程度的改造

实现:
function JSONP({ url, params, callbackKey, callback }) {
// 在参数⾥制定 callback 的名字 
params = params || {} 
params[callbackKey] = 'jsonpCallback' 
// 预留 callback 
window.jsonpCallback = callback 
// 拼接参数字符串 
const paramKeys = Object.keys(params) 
const paramString = paramKeys 
.map(key => `${key}=${params[key]}`) 
.join('&') 
// 插⼊ DOM 元素
const script = document.createElement('script') 
script.setAttribute('src', `${url}?${paramString}`) 
document.body.appendChild(script)
}

JSONP({ 
url: 'http://s.weibo.com/ajax/jsonp/suggestion', 
params: {
    key: 'test', 
},
callbackKey: '_cb',
callback(result) { 
console.log(result.data)
} 
})

2.postMessage()

HTML5 XMLHttpRequest 有⼀个API,postMessage()⽅法允许来⾃不同源的脚本采⽤异步⽅式进⾏有限的通信, 可以实现跨⽂本档、多窗⼝、跨域消息传递。

3.Nginx

nginx是⼀款极其强⼤的web服务器,其优点就是轻量级、启动快、⾼并发.

反向代理的原理很简单,即所有客户端的请求都必须先经过nginx的处理,nginx作为代理服务器再讲请求转发给node或 者java服务,这样就规避了同源策略。

#进程, 可更具cpu数量调整 
worker_processes 1; 
events { 
#连接数 
worker_connections 1024; 
}
http {
include mime.types; 
default_type 
application/octet-stream; 
sendfile on;
#连接超时时间,服务器会在这个时间过后关闭连接。
keepalive_timeout 10; 
# gizp压缩 gzip on; 
# 直接请求nginx也是会报跨域错误的这⾥设置允许跨域 
# 如果代理地址已经允许跨域则不需要这些, 否则报错(虽然这样nginx跨域就没意义了) 
add_header Access-Control-Allow-Origin *;
add_header Access-Control-Allow-Headers X-Requested-With;
add_header Access-Control-Allow-Methods GET,POST,OPTIONS; 
# srever模块配置是http模块中的⼀个⼦模块,⽤来定义⼀个虚拟访问主机 
server { 
listen 80; server_name localhost; 
# 根路径指到index.html 
location / { 
root html; 
index index.html index.htm; 
}
# localhost/api 的请求会被转发到192.168.0.103:8080 
location /api { 
rewrite ^/b/(.*)$ /$1 break; # 去除本地接⼝/api前缀, 否则会出现404
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_pass http://192.168.0.103:8080; # 转发地址
}

# 重定向错误⻚⾯到/50x.html
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}

}

}