什么是跨域?跨域解决方法

做为一名PHPer,被问到php如何实现跨域,当时一面懵逼,为啥?PHP的curl和file_get_contents这两个函数不都是可以跨域请求?php语言本身就支持跨平台,那么何来跨域说法,后来百度了一番,终于得到结果,php只是帮助浏览器实现跨域的一种手段,php本身并不存在跨域这一说法,广义的跨域是说W3C 下的浏览器跨域,ajax跨域!

1. 跨域是什么

跨域:当浏览器执行脚本时会检查是否同源,只有同源的脚本才会执行,如果不同源即为跨域。
当一个请求url的协议、域名、端口三者之间任意一个与当前页面url不同即为跨域

当前页面url 被请求页面url 是否跨域 原因
http://www.test.com/ http://www.test.com/index.html 同源(协议、域名、端口号相同)
http://www.test.com/ https://www.test.com/index.html 跨域 协议不同(http/https)
http://www.test.com/ http://www.baidu.com/ 跨域 主域名不同(test/baidu)
http://www.test.com/ http://blog.test.com/ 跨域 子域名不同(www/blog)
http://www.test.com/ http://www.test.com:7001/ 跨域 端口号不同(8080/7001)
  1. 这里的同源指访问的协议、域名、端口都相同。
  2. 同源策略是由 Netscape 提出的著名安全策略,是浏览器最核心、基本的安全功能,它限制了一个源中加载脚本与来自其他源中资源的交互方式。
  3. Ajax 发起的跨域 HTTP 请求,结果被浏览器拦截,同时 Ajax 请求不能携带与本网站不同源的 Cookie。
  4. // 向服务器test.com发出请求,该请求的查询字符串有一个callback参数,用来指定回调函数的名字 // 处理服务器返回回调函数的数据

    ②jQuery ajax:

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

    CORS 是跨域资源分享(Cross-Origin Resource Sharing)的缩写。它是 W3C 标准,属于跨源 AJAX 请求的根本解决方法。

    1. 普通跨域请求:只需服务器端设置Access-Control-Allow-Origin
    2. 带cookie跨域请求:前后端都需要进行设置 ,根据xhr.withCredentials字段判断是否带有cookie

    ①原生ajax

    var xhr = new XMLHttpRequest(); // IE8/9需用window.XDomainRequest兼容
    // 前端设置是否带cookie
    xhr.withCredentials = true;
    xhr.open('post', 'http://www.domain2.com:8080/login', true);
    xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    xhr.send('user=admin');
    xhr.onreadystatechange = function() {
        if (xhr.readyState == 4 && xhr.status == 200) {
            alert(xhr.responseText);
        }
    };
    

    ②jQuery ajax:

    
    $.ajax({
       url: 'http://www.test.com:8080/login',
       type: 'get',
       data: {},
       xhrFields: {
           withCredentials: true    // 前端设置是否带cookie
       },
       crossDomain: true,   // 会让请求头中包含跨域的额外信息,但不会含cookie
    });
    

    服务端设置
    服务器端对于CORS的支持,主要是通过设置Access-Control-Allow-Origin来进行的。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。

    1. 允许所有域名访问
      header("Access-Control-Allow-Origin:*");
    2. 允许指定的域名访问
      header("Access-Control-Allow-Origin:http://www.test123.com");
    3. 允许多个域名访问
    $origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : '';  
      
    $allow_origin = [
        'http://www.test123.com',
        'http://www.test456.com'
    ];
    if(in_array($origin, $allow_origin)) {
        header("Access-Control-Allow-Origin:{$origin}");
    }
    

    参考主要文章有以下,两篇文章都写的非常好!

    https://blog.csdn.net/meism5/article/details/90414283
    https://blog.csdn.net/qq_38128179/article/details/84956552

你可能感兴趣的:(什么是跨域?跨域解决方法)