使用 XMLHttpRequest(五):跨域 HTTP 请求


CORS_SameOrginPolicy.jpg

作为同源策略的一部分,XMLHttpRequest 对象通常仅可以发起和文档具有相同域名的 HTTP 请求。

XHR2 通过在 HTTP 响应中发送合适的 CORS(Cross-Origin Resource Sharing,跨域资源共享)允许跨域访问网站。

虽然 CORS 支持的跨域请求不需要做任何事情,但是有一些安全细节需要了解:

  • 如果 XMLHttpRequest 对象的 open() 方法中传入了用户名和密码,那么它们绝不能通过跨域发送请求;
  • 跨域请求也不会包含任何用户证书,比如 cookie、token 等。

下面来看一个示例:

/**
 * 使用 HEAD 和 CORS 请求链接详细信息
 */
whenReady(function () {
    // 测试浏览器是否支持 CORS
    var supportCORS = (new XMLHttpRequest()).withCredentials !== undefined;
    
    var links = document.getElementsByTagName("a");
    for (var i = 0; i < links.length; i++) {
        var link = links[i];
        if (!link.href)
            continue;
        if (link.title)
            continue;
        if (link.host !== location.host || link.protocol !== location.protocol) {
            link.title = "站外链接";
            if (!supportCORS)
                continue;
        }
    
        if (link.addEventListener) {
            link.addEventListener("mouseover", mouseoverHandler, false);
        } else {
            link.attachEvent("onmouseover", mouseoverHandler);
        }
    }
    
    function mouseoverHandler(e) {
        var link = e.target || e.srcElement;
        var url = link.href;
    
        var req = new XMLHttpRequest();
        req.open("HEAD", url);
        req.onreadystatechange = function () {
            if (req.readyState !== 4)
                return;
            if (req.status === 200) {
                var type = req.getResponseHeader("Content-Type");
                var size = req.getResponseHeader("Content-Length");
                var date = req.getResponseHeader("Last-Modified");
                link.title = "类型: " + type + " \n" +
                        "大小: " + size + " \n" + "时间:" + date;
            } else {
                if (!link.title) {
                    link.title = "无法访问网页: \n" + req.status + " " + req.statusText;
                }
            }
        };
        req.send(null);
    
        if (link.removeEventListener) {
            link.removeEventListener("mouseover", mouseoverHandler, false);
        } else {
            link.detachEvent("onmouseover", mouseoverHandler);
        }
    }
});

Vote Vote Cancel Collect Collect Cancel

<< 上一篇: 使用 XMLHttpRequest(四):中止请求和超时

>> 下一篇: 发送 JSONP 请求