浏览器的同源策略(Same origin policy)约定:“协议+域名+端口”三者相同,即使不同的域名指向同一ip地址,也非同源; 如果缺少同源策略,浏览器很容易受到XSS、CSRF攻击。
1、通过jsonp跨域
封装一个可用的JSONP方法,示例如下:
function jsonp(url, params, callback) {
// 生成唯一的回调函数名
const callbackName = 'jsonp_' + Date.now();
// 将参数拼接到 URL 中
const queryStr = Object.keys(params)
.map(key => encodeURIComponent(key) + '=' + encodeURIComponent(params(key)))
.join('&'); // user=admin&age=18
// 创建 script 元素
const script = document.createElement("script");
script.src = url + '?' + queryStr + '&callback=' + callbackName;
// 定义回调函数
window[callbackName] = function(data) {
// 调用回调函数
callback(data);
// 删除 script 元素和回调函数
document.head.removeChild(script);
delete window[callbackName];
};
// 将 script 元素添加到页面中
document.head.appendChild(script);
}
使用示例:
jsonp('http://www.example.com/api', { user: 'admin', age: 18 }, function(data){
console.log(data);
})
jsonp
函数接受三个参数: URL、参数对象 和 回调函数。它会生成一个唯一的回调函数名,并将参数拼接到 URL 中,然后创建一个 <script>
元素,并将URL设置为带有回调函数名的URL。定义一个全局的回调函数,当响应返回时调用该回调函数,并将数据传递给回调函数。最后将 <script>
元素添加到页面中,触发跨域请求,删除 <script>
元素和回调函数。
2、document.domain + iframe 跨域
此方案仅限主域相同,子域不同时的跨域应用场景
1)、父窗口:(http://www.domain.com/a.html)
<iframe id = "iframe" src ="http://child.domain.com/b.html"></iframe>
<script>
document.domain = 'domain.com';
var user ='admin';
</script>
2)、子窗口:(http://child.domain.com/b.html)
document.domain = 'domain.com';
// 获取父窗口的变量
alert('get js data from parent ---> ' + window.parent.user );
3、nginx代理跨域
通过nginx配置反向代理,将跨域请求转发到同源接口,从而避免浏览器的同源策略限制,示例:
server {
listen 80;
server_name your-domain.com;
location /api {
# 设置代理目标地址
proxy_pass http://api.example.com;
# 设置允许的跨域请求头
add_header Access-Control-Allow-Origin $http_origin;
add_header Access-Control-Allow-Methods "GET, POST, OPTIONS";
add_header Access-Control-Allow-Credentials true;
add_header Access-Control-Allow-Headers "Origin, X-Requested-With, Content-Type, Accept";
# 处理预检请求(OPTIONS 请求)
if ($request_method = OPTIONS) {
return 200;
}
}
}
在上面的示例中,假设你的域名是 your-domain.com,需要代理访问 api.example.com。你可以将这个配置添加到 Nginx 的配置文件中。
这个配置会将 /api 路径下的请求代理到 http://api.example.com。同时,通过添加 Access-Control-Allow-* 头部,允许跨域请求的来源、方法、头部等。
这样,当你在前端发送请求到 /api 路径时,Nginx 会将请求代理到 http://api.example.com,并在响应中添加跨域相关的头部,从而解决跨域问题。注意要根据实际情况进行配置,包括监听的端口、域名和代理的目标地址等。