首页 > 编程知识 正文

前端解决跨域问题的8种方案(最新最全)用法介绍

时间:2023-11-20 17:07:47 阅读:293040 作者:BJZR

本文将从多个方面对前端解决跨域问题的8种方案(最新最全)进行详细的阐述。

一、JSONP跨域方案

JSONP(JSON with Padding)是一种跨域请求方案。它通过动态创建<script>标签,向服务器发起请求,服务器返回指定函数调用的数据,实现数据获取。

首先,定义一个处理数据的函数,将该函数名传递给服务器端:

  
    function handleData(data){
      console.log(data); // 处理数据
    }
    <script src="http://www.example.com/data.php?callback=handleData"></script>
  

服务器返回的数据格式如下:

  
    handleData({"id":1,"name":"jack"});
  

优点:对于低版本的浏览器,JSONP方案是最可行的解决方案。

缺点:对于非GET请求,不能使用JSONP解决跨域问题。另外,JSONP获取的数据只能是JSON格式的。

二、CORS跨域方案

跨域资源共享(CORS,Cross-Origin Resource Sharing)标准允许像其他域发送XMLHttpRequest请求。该标准需要浏览器和服务器都支持。浏览器会在请求头中携带一个Origin字段来告诉服务器请求的来源,服务器通过在响应头中设置Access-Control-Allow-Origin字段来允许或禁止请求。

在前端可以通过设置XMLHttpRequest的withCredentials属性来携带跨域的凭据(cookie等)。在服务器端,需要设置Access-Control-Allow-Credentials字段为true才能接受跨域的凭据。

代码示例:

  
  var xhr = new XMLHttpRequest();
  xhr.withCredentials = true;
  xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
      console.log(xhr.responseText);
    }
  }
  xhr.open('POST', 'http://www.example.com');
  xhr.send();
  

对应服务器端的代码:

  
  header("Access-Control-Allow-Origin: http://www.example.com");
  header("Access-Control-Allow-Credentials: true");
  

优点:使用简单,支持所有类型的HTTP请求,请求与响应的信息更丰富。

缺点:比较麻烦,需要在服务器端设置。另外,IE10以下的浏览器不支持CORS。

三、WebSocket跨域方案

WebSocket是HTML5中新增的一种网络通信协议。因为它能在浏览器与服务器之间建立持久性的连接,使用它进行通信相对于HTTP请求来说更加灵活和高效。

WebSocket跨域通信同样需要跨域的服务器端支持。如果浏览器与服务器端都支持WebSocket,那么就可以在JavaScript代码中直接使用WebSocket API建立连接。

代码示例:

  
  var ws = new WebSocket('ws://www.example.com/server');
  ws.onopen = function(){
    ws.send('Hello Server!');
  }
  ws.onmessage = function(event){
    console.log(event.data);
  }
  

优点:支持双向通信,速度快,消息实时性强。

缺点:需要浏览器与服务器端都支持WebSocket,需要跨域的服务器端支持。

四、代理跨域方案

代理跨域方案指的是,前端将请求发送给本地服务器,后端的本地服务器将请求发送给目标服务器,接收到响应后再将响应返回前端。

代码示例:

  
  var proxyUrl = 'http://www.example.com/proxy';
  var targetUrl = 'http://www.target.com';
  var xhr = new XMLHttpRequest();
  xhr.onreadystatechange = function(){
    if(xhr.readyState === 4 && xhr.status === 200){
      console.log(xhr.responseText);
    }
  }
  xhr.open('GET', proxyUrl + '?url=' + encodeURIComponent(targetUrl));
  xhr.send();
  

对应本地服务器的代码:

  
  var request = require('request');
  var express = require('express');
  var app = express();
  app.get('/proxy', function(req, res){
    var url = req.query.url;
    request(url, function(error, response, body){
      if(!error && response.statusCode === 200){
        res.setHeader('Content-Type', 'application/json;charset=utf-8');
        res.send(body);
      }
    });
  });
  app.listen(3000, function(){
    console.log('Proxy server is running at port 3000.');
  });
  

优点:容易实现,适用于各种类型的HTTP请求,支持跨域访问所有资源。

缺点:不适用于大量并发请求,需要自己搭建代理服务器。

五、Nginx反向代理跨域方案

Nginx是一款高性能的Web服务器和反向代理服务器。通过设置Nginx服务器作为前端浏览器与目标服务器之间的代理服务器,将所有的请求和响应都转发到Nginx上,再由Nginx将请求转发给目标服务器,实现跨域请求。

代码示例:

  
  server {
    listen 80;
    server_name www.example.com;
    location / {
      proxy_pass http://www.target.com;
      add_header Access-Control-Allow-Origin *;
    }
  }
  

优点:适用于大量并发请求,易于配置,在服务端实现跨域。

缺点:需要一定的服务器管理经验,适用于HTTP请求。

六、postMessage跨域方案

HTML5中的postMessage允许跨窗口通信,可用于在两个不同域之间传递数据,从而实现跨域通信。

代码示例:

  
  // 在iframe所在的页面中
  var targetOrigin = "http://www.example.com";
  window.onload = function(){
    var iframeWin = document.getElementById("iframe").contentWindow;
    iframeWin.postMessage("hello",targetOrigin);
  }

  // 在被嵌套的iframe页面中
  window.onmessage = function(event){
    if(event.origin === 'http://www.target.com'){
      console.log(event.data); // "hello"
      event.source.postMessage("world", "http://www.example.com");
    }
  }
  

优点:可方便地在两个不同域之间进行跨域通信。

缺点:由于postMessage自身的特性,接收方需要能够知道消息的来源,存在一定的安全问题。

七、document.domain跨域方案

document.domain方案只适用于主域名相同,子域名不同的跨域访问场景。通过将两个彼此通信的页面的document.domain都设置为相同的主域名,就可以实现页面之间的跨域访问。

代码示例:假设两个跨域的页面为"http://www.a.example.com/"和"http://www.b.example.com/",则可以在这两个页面中添加如下代码:

  
  // 在a.example.com中设置
  document.domain = 'example.com';

  // 在b.example.com中设置
  document.domain = 'example.com';
  

优点:简单易用,不需要修改服务器端的配置。

缺点:只适用于主域名相同,子域名不同的场景。

八、跨域资源嵌入跨域方案

在跨域资源嵌入跨域方案中,前端将目标地址嵌入页面中,请求嵌入的地址时使用script标签、link标签等形式进行,服务器端返回的数据会被嵌入到页面中进行执行。在返回结果时,如果成功,则可以利用回调函数或者状态码的方式将结果传递给前端代码。

代码示例:

  
  // 使用script标签请求跨域嵌入资源
  <script src="http://www.target.com/resource?callback=handleData"></script>
  function handleData(data){
    console.log(data);
  }
  

对应目标服务器端的代码:

  
  $callback = $_GET["callback"];
  $data = array("id"=>1, "name"=>"jack");
  header("Content-Type:application/json;charset=utf-8");
  echo $callback.'('.json_encode($data).')';
  

优点:简单易用,适用于各种类型的HTTP请求。

缺点:需要进行字符串处理,存在一定的安全风险。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。