前端跨域

2020-01-10  本文已影响0人  Viker_bar

什么是跨域?

跨域是指一个域下的文档或脚本试图去请求另一个域下的资源,这里跨域是广义的。
通常我们所说的跨域是狭义的,是由浏览器同源策略限制的一类请求场景

什么是同源策略?

同源策略/SOP(Same origin policy)是一种约定,由Netscape公司1995年引入浏览器,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,浏览器很容易受到XSS、CSFR等攻击。所谓同源是指"协议+域名+端口"三者相同

常见跨域场景

跨域场景

解决方案

1、 通过jsonp跨域
2、 跨域资源共享(CORS)
3、 nginx代理跨域

一:通过jsonp跨域

/***
*  就是利用<script>标签没有跨域限制的“漏洞”来达到与第三方通讯的目的。
*  当需要通讯时,本站脚本创建一个<script>元素,地址指向第三方的API网址,
*  形如:<script src="http://www.baidu.com/api?param1=1&param2=2"></script>     
*  并提供一个回调函数来接收数据(函数名可约定,或通过地址参数传递)    
*  第三方产生的响应为json数据的包装(故称之为jsonp,即json padding),
*  形如:handleCallback({"name":"hax","gender":"Male"})     这样浏览器会调用callback函数,
*  并传递解析后  json对象作为参数
***/

//原生写法
var script = document.createElement('script');
script.type = 'text/javascript';

// 传参一个回调函数名给后端,方便后端返回时执行这个在前端定义的回调函数
script.src = 'http://www.baidu.com:8080/api?user=admin&callback=handleCallback';
document.head.appendChild(script);

// 回调执行函数
function handleCallback(res) {
    alert(JSON.stringify(res));
}

//jquery写法
$.ajax({
    url: 'http://www.baidu.com:8080/api',
    type: 'get',
    dataType: 'jsonp',  // 请求方式为jsonp
    jsonpCallback: "handleCallback",    // 自定义回调函数名
    data: {}
});

jsonp缺点:只能实现get一种请求。

二:跨域资源共享(CORS)

CORS是一个W3C标准,全称是"跨域资源共享"(Cross-origin resource sharing)。
它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源的限制。

CORS需要浏览器和服务器同时支持。目前,所有浏览器都支持该功能,IE浏览器不能低于IE10
(IE8/9需要使用XDomainRequest对象来支持CORS)

浏览器将CORS请求分成两类:简单请求(simple request)和非简单请求(not-so-simple request)
这里只介绍简单请求,非简单请求可点击这里

实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信

// 1:服务端不需要cookie信息的情况
前端:什么都不用做
后端:Access-Control-Allow-Origin :  //必须  http://domain.com 或 * 号
     Access-Control-Allow-Credentials  //可选
     Access-Control-Expose-Headers   //可选

// 2:服务端需要cookie信息的情况
前端:在AJAX请求中打开withCredentials = true
后端: Access-Control-Allow-Origin :  //必须  http://domain.com,且不能为 * 号 
      Access-Control-Allow-Credentials: //必须  true
      Access-Control-Expose-Headers: //可选

三:nginx代理跨域

server {
       listen       80;
       server_name m.youmias.com;

       location / {
           proxy_pass http://123.57.216.192:8080;  //个人公网ip
           proxy_set_header Host $host;
           proxy_redirect off;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
           proxy_connect_timeout 60;
           proxy_read_timeout 600;
           proxy_send_timeout 600;
       }

       location /api {
           rewrite ^/api/(.*)$ /$1 break;
           proxy_pass http://123.57.216.192:8080; //个人公网ip
           proxy_set_header Host $host;
           proxy_redirect off;
           proxy_set_header X-Real-IP $remote_addr;
           proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
       }

       error_page 404 /404.html;
           location = /40x.html {
       }

       error_page 500 502 503 504 /50x.html;
           location = /50x.html {
       }
   }
上一篇 下一篇

猜你喜欢

热点阅读