📌  相关文章
📜  网络技术问题 | JavaScript 课程测验 2 |问题 3(1)

📅  最后修改于: 2023-12-03 15:41:21.407000             🧑  作者: Mango

网络技术问题 | JavaScript 课程测验 2 |问题 3

本题考查的是对 Ajax 请求的处理能力。

问题描述

你正在开发一个 Web 应用程序,需要通过 Ajax 请求从后端获取数据。你已经编写了以下代码:

const url = "https://myapi.com/data";
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.send();

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    const responseData = JSON.parse(xhr.responseText);
    // TODO: 在这里处理响应数据
  }
};

但是,你发现有时候这段代码会因为跨域问题而无法正常工作。你该怎么办?

解决方案

跨域问题指的是在 Web 应用程序中,通过 Ajax 请求获取的数据源和应用程序所在的域名不同。出于安全考虑,Web 浏览器会限制跨域请求。而由于上述代码没有对跨域请求进行处理,因此有时候无法正确工作。

要解决这个问题,需要使用 JSONP 或 CORS 等跨域技术。下面分别介绍这两种技术的使用方法。

JSONP

JSONP 全称是 JSON with Padding,是一种跨域技术。它利用了 script 标签不会受到跨域限制的特点,通过动态创建 script 标签,并指定回调函数名的方式,实现跨域数据的传输。

具体来说,就是服务器端返回一段 JavaScript 代码,代码中包含一个函数调用,函数名是由客户端生成的随机字符串。客户端接收到这段代码后,通过动态创建 script 标签的方式将代码插入到页面中。由于代码中包含了一个回调函数调用,因此,页面会自动调用这个函数。服务器端在回调函数中返回需要传递的数据,由客户端接收并处理。

在 JavaScript 中使用 JSONP 的方法如下:

function handleResponse(responseData) {
  //TODO: 在这里处理响应数据
}

const script = document.createElement("script");
script.src = "https://myapi.com/data?callback=handleResponse";
document.head.appendChild(script);

在上面的代码中,callback 参数用于指定回调函数名。服务器端应该在返回的 JavaScript 代码中,使用该函数名来调用回调函数。

需要注意的是,使用 JSONP 有一些安全风险。因为回调函数名由客户端控制,在某些情况下可能会被滥用。因此,在实际使用时,需要确保服务器端正确处理 JSONP 请求,并进行一些必要的安全检查。

CORS

CORS 是跨域资源共享(Cross-Origin Resource Sharing)的缩写。它是一种使用标准 HTTP 头部来告诉浏览器,哪些跨域请求是被允许的。CORS 机制可以让 Web 应用程序获得跨域访问其他域名下的资源的权限。CORS 的具体实现需要在服务器端进行配置,同时前端 JavaScript 也需要正确设置一些参数。

修改上述代码,让它支持 CORS 的方式如下:

const url = "https://myapi.com/data";
const xhr = new XMLHttpRequest();
xhr.open("GET", url);
xhr.setRequestHeader("Content-Type", "application/json");
xhr.withCredentials = true; // 需要允许带上 cookie
xhr.send();

xhr.onreadystatechange = function () {
  if (xhr.readyState === 4 && xhr.status === 200) {
    const responseData = JSON.parse(xhr.responseText);
    // TODO: 在这里处理响应数据
  }
};

在上面的代码中,我们通过设置 withCredentials 属性来允许浏览器带上 cookie,从而实现跨域请求。同时,我们还设置了 Content-Type 头部,以告诉服务器请求的数据类型。

另外,服务器端还需要设置响应头部来支持 CORS,代码如下:

from starlette.middleware.cors import CORSMiddleware

app.add_middleware(
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

在上面的代码中,我们使用了 Starlette 框架提供的 CORS 中间件。中间件可以很方便地给应用程序添加 CORS 支持。在这里,我们设置了允许所有来源的请求,并支持任意方法和头部。

总结

在 Web 应用程序开发中,跨域问题是比较常见的。在处理 Ajax 请求时,需要注意处理跨域请求。本篇文章介绍了 JSONP 和 CORS 两种跨域技术的使用方法,希望能对你有所帮助。