JavaScript中跨域问题的深入理解

JavaScript中跨域问题的深入理解

什么是跨域请求

在Web开发中,当a.com的JavaScript通过XMLHttpRequest发起对b.com的请求,此时在浏览器中会因为同源策略(Same-Origin Policy)而被阻止,这个错误就是跨域请求报错。同源策略是由浏览器同源策略规定的一个标准来限制页面脚本在不同域的文档/源中进行交互的安全机制。

当协议,域名或者端口号有任何一个不同的时候,我们都认为这是跨域请求。

常用结局跨域请求的方法

JSONP

JSONP (JSON with padding)是一种跨域请求的技术。JSONP并不是一种新的网络请求方式,而是一种网页在服务器上动态生成JSON数据的技术,在“JSON”和“Padding”二者的帮助下完成了在不同来源之间获取数据的任务。

  1. JSONP的原理

(1) 前端代码定义一个callback回调函数。

(2) 发起一个GET请求,并且请求的URL中包含callback回调函数的名称和随机数(防止缓存)。

(3) 服务器接受请求后,将数据打包成一个JSON对象,并将callback函数的名称和数据一起返回给前端(JavaScript)。

(4) 前端拿到响应结果后,会自动的调用callback回调函数,并将响应结果作为参数传入。

示例代码:

前端代码:

function handleResponse(data) { 
   console.log(data);
}
var script = document.createElement('script');
script.src = 'https://xxx.com/test?callback=handleResponse';
document.body.appendChild(script);

后端代码:

function test(request, response) { 
   // 拼接数据和callback函数名称
   const res = JSON.stringify({ a: 1, b: 2 })
   const callback = request.query.callback
   response.end(callback + '(' + res + ')')
}
  1. JSONP的缺点

  2. 只支持GET方法

  3. 存在安全风险(难以避免XSS攻击)

CORS

CORS(Cross-Origin Resource Sharing,跨源资源共享)是W3C标准,是目前最完善的解决跨域问题的方案。通过在Response header中添加一些验证信息,CORS可以在不需要前端或后端做任何特殊处理的情况下进行跨源请求,在安全和性能两方面都具有优势。

CORS可以使用以下方式验证:

  • Origin:表示请求方的域名。
  • Access-Control-Allow-Origin:表示允许这个域的哪些请求可以通过。
  • Access-Control-Allow-Credentials:是否允许携带cookie,值为true或false
  • Access-Control-Allow-Methods:表示允许这个域的哪些请求方法可以通过。例如:GET, POST, PATCH, PUT, DELETE。
  • Access-Control-Allow-Headers:表示允许这个域的哪些请求头可以通过。例如:content-type,x-requested-with。

示例代码:

前端代码:

fetch('https://xxx.com/test', {
    method: 'GET',
    headers: {
        'Content-Type': 'application/json'
    },
    credentials: 'include'
})
    .then(response => response.json())
    .then(data => console.log(data))
    .catch(error => console.error(error));

后端代码:

function test(request, response) { 
   // 设置允许接收跨域访问的源名称
    response.setHeader('Access-Control-Allow-Origin', 'https://foo.com,https://bar.com');
    // 允许跨域访问的http请求方法
    response.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
    response.setHeader('Access-Control-Allow-Credentials', true);
    response.setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Content-Type');
    if (request.method === "OPTIONS") {
        response.end();
        return;
    }
    const res = JSON.stringify({ a: 1, b: 2 });
    response.end(res);
}

代理请求

服务器端以后端接口调用为例,代码如下。具体思路:

  1. 前端通过jQuery、axios、fetch等库将请求发送给自己的服务器(本地服务器和接口服务器跨域)
  2. 后台接收到请求,再将请求转发给接口服务器
  3. 将接口服务器返回的数据原封不动的返回给前端。

优点:

不需要前端和后端进行配置,只需要后端对代理服务器进行设置。

缺点:

会增加代理层的成本和复杂度

示例代码:

前端代码:

fetch('https://xxx.com/api/test', {
        method: 'GET',
        headers: {
          'Content-Type': 'application/json; charset=UTF-8',
        },
      })
      .then(res => res.json())
      .then(data => {
        this.setState({
          data: data,
        });
      })
      .catch(error => {
        console.log(error);
      });

后端代码:

const proxyRequest = (req, res) => {
  const targetUrl = "https://xxx.com";
  // 此处应解析前端发送的请求数据并转发给对应的API接口
  // 请求转发
  const url = targetUrl + req.url;
  const options = {
    url: url,
    method: req.method,
  };
  request(options, (err, response, body) => {
    if (!err && response.statusCode === 200) {
      const info = JSON.parse(body);
      res.json(info || {});
    } else {
      res.sendStatus(500);
    }
  });
};

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JavaScript中跨域问题的深入理解 - Python技术站

(0)
上一篇 2023年5月13日
下一篇 2023年5月13日

相关文章

  • Apex英雄下载提示4-400错误怎么办 下载失败4-400报错解决方法分享

    以下是关于“Apex英雄下载提示4-400错误怎么办下载失败4-400报错解决方法分享”的完整攻略: 简介 Apex英雄是一款非常受欢迎的多人在线射击游戏。在下载和安装Apex英雄时,有时会遇到4-400错误,导致下载失败。本文将介绍如何解决Apex英雄下载提示4-400错误的问题。 问题描述 在下载和安装Apex英雄时,有时会遇到4-400错误,致下载失败…

    http 2023年5月13日
    00
  • HTTP的会话管理机制是什么?

    HTTP的会话管理机制可以分为两个方面,即Cookie和Session。 Cookie Cookie是HTTP协议中的一个机制,它用来存储一个持久化的客户端状态信息,这个信息可以被同一服务器的多个页面和/或应用程序共享和访问。它的主要作用是在客户端保存会话状态信息,当下次客户端发送请求时,会通过请求头将这些Cookie信息传给服务器。 例如,一个用户登录了一…

    Http网络协议 2023年4月20日
    00
  • apache启动报错:httpd: apr_sockaddr_info_get() failed

    以下是关于“apache启动报错:httpd:apr_sockaddr_info_get()failed”的完整攻略: 问题描述 在启动Apache服务器时,我们可能会遇到httpd:apr_sockaddr_info_get()failed的错。这个问题通常是由于Apache无法解析主机名或IP地址导致的。下面我们将介绍如何解决Apache动报错:http…

    http 2023年5月13日
    00
  • Java之SpringBoot-Thymeleaf详情

    Java之SpringBoot-Thymeleaf详情 本攻略旨在介绍如何使用SpringBoot框架搭建一个基于Thymeleaf模板引擎的Web应用程序。其中包含以下主题: 什么是SpringBoot? 什么是Thymeleaf模板引擎? 如何搭建一个基于SpringBoot和Thymeleaf的Web应用程序? 示例1:基于Thymeleaf的静态页面…

    http 2023年5月13日
    00
  • SpringBoot项目启动报错踩坑实战记录

    下面是“SpringBoot项目启动报错踩坑实战记录”的攻略,包含以下几个方面: 标题 在markdown中,使用#号表示标题的级别,一个#表示一级标题,两个#表示二级标题,以此类推。在本文中,使用一级标题,即使用一个#号。 问题描述 本文讲述的是“SpringBoot项目启动报错踩坑”的实战记录。在开发过程中,我们可能会遇到各种各样的报错信息,例如:Cla…

    http 2023年5月13日
    00
  • springcloud gateway设置context-path的操作

    下面是关于“Spring Cloud Gateway 设置 Context Path”的完整攻略。 什么是 Context Path Context Path,即上下文路径,是指Web应用程序根目录下对应URL路径的名称,也可以称之为应用程序的基路径。 例如,我们有一个微服务应用程序“user-service”,我们将其设置了 Context Path 为“…

    http 2023年5月13日
    00
  • HTTP头部信息有哪些?

    HTTP头部信息是HTTP协议中的一部分,包含了对请求或响应的描述和信息。它是由一些由冒号分隔的名值对组成的,包含了一些标准的属性和一些特定的定制属性。HTTP头部信息中的属性可以提供有关消息体内容、客户端、服务器、缓存、安全性等方面的信息。 常用的HTTP头部信息包括: Accept:指定客户端可以处理的响应内容类型。 示例: Accept: text/h…

    Http网络协议 2023年4月20日
    00
  • HTTP 499 状态码 nginx下 499错误的解决办法

    以下是关于“HTTP499状态码nginx下499错误的解决办法”的详细攻略: 问题描述 在使用Nginx作Web服务器时,有时我们会遇到HTTP499状态的错误。这种错误通常是由于客户端在请求过程中主动关闭了连接导致的。下面我们将介如解决这个问题。 解决方法 方法一:检查客户端是否主动了连接 在Nginx中,HTTP499状态码表示客户端请求过程中主动关闭…

    http 2023年5月13日
    00
合作推广
合作推广
分享本页
返回顶部