1

前端跨域请求方案实现_mb66062e5f7b71d的技术博客_51CTO博客

 1 month ago
source link: https://blog.51cto.com/u_16660733/10253751
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前端跨域请求方案实现

精选 原创

跨域(Cross-Origin)指的是在 Web 开发中,当一个网页的文档、脚本或资源请求来自于另一个域(域名、协议或端口任意一个不同),就会发生跨域。浏览器出于安全考虑,采用同源策略(Same-Origin Policy)来限制页面对不同源的资源的访问。

同源策略的主要原则是,页面中的脚本(如 JavaScript)只能读取来自相同域的数据,不能执行访问不同域的操作。这种限制是为了防止潜在的安全风险,比如防止恶意网站通过脚本获取用户的敏感信息。

同源策略的限制包括以下几个方面:

Cookie、LocalStorage 和 IndexDB 限制: 页面只能读取自己域下的 Cookie、LocalStorage 和 IndexDB,不能读取其他域下的信息。

DOM 限制: 页面中的脚本只能操作和访问自己域下的 DOM,不能访问其他域的 DOM。

AJAX 请求限制: 使用 XMLHttpRequest 进行的 AJAX 请求,受到同源策略的限制,不能向不同域的地址发起请求。

Frame 和 iframe 限制: 嵌套的页面(frame 或 iframe)只能与父页面同源。

为了在特定情况下实现跨域请求,可以使用一些方法,如使用 JSONP、CORS(Cross-Origin Resource Sharing)、代理服务器等。这些方法可以绕过同源策略的限制,但需要注意安全性和适用性。

一、iframe实现get跨域请求方案

var sendGetRequest = function(url, params, callback) {
        var iframe = document.createElement('iframe');
        iframe.name = 'getFrame';
        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        var fullUrl = buildUrlWithParams(url, params);
        var timestamp = new Date().getTime();
        var uniqueUrl = fullUrl + '×tamp=' + timestamp;

        iframe.src = uniqueUrl;

        iframe.onload = function() {
            var iframeContent = iframe.contentDocument.body.textContent || iframe.contentDocument.body.innerText;
            callback(iframeContent);
            document.body.removeChild(iframe);
        };
    }
var buildUrlWithParams = function(url, params) {
        var queryString = Object.keys(params)
            .map(function(key) {
                return encodeURIComponent(key) + '=' + encodeURIComponent(params[key]);
            })
            .join('&');
        return url + (url.indexOf('?') !== -1 ? '&' : '?') + queryString;
    }

二、iframe+form实现post跨域请求方案

var sendPostRequest = function(url, data, callback) {
        var iframe = document.createElement('iframe');
        iframe.name = 'postFrame';
        iframe.style.display = 'none';
        document.body.appendChild(iframe);

        var form = document.createElement('form');
        form.action = url;
        form.method = 'post';
        form.target = 'postFrame';
        document.body.appendChild(form);

        for (var key in data) {
            if (data.hasOwnProperty(key)) {
                var input = document.createElement('input');
                input.type = 'hidden';
                input.name = key;
                input.value = data[key];
                form.appendChild(input);
            }
        }

        iframe.onload = function() {
            var iframeContent = iframe.contentDocument.body.textContent || iframe.contentDocument.body.innerText;
            callback(iframeContent);
            document.body.removeChild(iframe);
            document.body.removeChild(form);
        };

        form.submit();
    },

三、jsonp实现get跨域请求方案

var sendJsonpRequest = function(url, params, callbackName, callback) {
        var script = document.createElement('script');
        script.src = this.buildUrlWithParams(url, params) + '&callback=' + callbackName;
        document.head.appendChild(script);

        // 回调函数
        window[callbackName] = function(data) {
            callback(data);
            document.head.removeChild(script);
            delete window[callbackName];
        };
    }

四、iframe与postMessage结合可以实现get请求的跨域方案

1、首先,创建一个 HTML 文件(例如,iframe-parent.html),其中包含一个 iframe 和相应的脚本:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Parent Page</title>
</head>
<body>
    <iframe id="targetFrame" src="https://example.com/child-page.html" style="display:none;"></iframe>

    <script>
        window.addEventListener('message', function(event) {
            if (event.origin === 'https://example.com') {
                console.log('Received data from child page:', event.data);
            }
        });

        function sendGetRequest() {
            var iframe = document.getElementById('targetFrame');
            iframe.contentWindow.postMessage('GET_REQUEST', 'https://example.com');
        }

        // Trigger the GET request when the parent page loads
        sendGetRequest();
    </script>
</body>
</html>

在这个示例中,父页面通过 iframe 加载了一个子页面,并在子页面加载后发送了一个 GET 请求的消息。

2、接下来,创建子页面的 HTML 文件(例如,child-page.html):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Child Page</title>
</head>
<body>
    <script>
        window.addEventListener('message', function(event) {
            if (event.origin === 'https://example.com' && event.data === 'GET_REQUEST') {
                // Simulate processing and send back the response to the parent page
                var responseData = 'This is the response data for the GET request.';
                window.parent.postMessage(responseData, 'https://example.com');
            }
        });
    </script>
</body>
</html>

在子页面中,监听 message 事件,当收到来自父页面的 GET 请求消息时,可以进行相应的处理,并通过 postMessage 发送响应数据回父页面。

请注意,这种方式的跨域通信需要确保父子页面之间建立了信任关系,即父页面加载的子页面来自相同的域。在实际应用中,也可以考虑使用更为复杂的跨域通信方案,例如使用 window.location.hash 或动态创建


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK