了解 jQuery 中的 CORS 错误,但不能了解 Postman 中的 CORS 错误

了解 jQuery 中的 CORS 错误,但不能了解 Postman 中的 CORS 错误
JavaScript

为什么浏览器会出现CORS错误?

使用 JavaScript 连接到 RESTful API 时,您可能会遇到“请求的资源上不存在‘Access-Control-Allow-Origin’标头”错误。此错误通常是由于浏览器的同源策略而发生的,该策略限制网页向与提供该网页的域不同的域发出请求。

有趣的是,当通过Postman等工具发出相同的请求时,不会出现这样的错误。这种差异可能会让开发人员感到困惑。了解为什么 XMLHttpRequest 或 fetch 调用会在浏览器中被 CORS 阻止,但在 Postman 中不会被阻止,这对于故障排除和开发安全 Web 应用程序至关重要。

使用 Flask 后端解决 JavaScript 中的 CORS 问题

使用 jQuery 的 JavaScript 前端代码

// JavaScript (jQuery) frontend script
$(document).ready(function() {
  $("#loginButton").click(function() {
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: 'http://localhost:5000/login',
      data: JSON.stringify({
        username: 'user',
        password: 'pass'
      }),
      contentType: 'application/json',
      crossDomain: true,
      xhrFields: {
        withCredentials: true
      }
    }).done(function(data) {
      console.log('Login successful');
    }).fail(function(xhr, textStatus, errorThrown) {
      alert('Error: ' + xhr.responseText);
    });
  });
});

在 Flask 中设置 CORS

使用 Flask 的 Python 后端代码

# Python (Flask) backend script
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if username == 'user' and password == 'pass':
        return jsonify({'message': 'Login successful'}), 200
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

使用 Flask 后端解决 JavaScript 中的 CORS 问题

使用 jQuery 的 JavaScript 前端代码

// JavaScript (jQuery) frontend script
$(document).ready(function() {
  $("#loginButton").click(function() {
    $.ajax({
      type: 'POST',
      dataType: 'json',
      url: 'http://localhost:5000/login',
      data: JSON.stringify({
        username: 'user',
        password: 'pass'
      }),
      contentType: 'application/json',
      crossDomain: true,
      xhrFields: {
        withCredentials: true
      }
    }).done(function(data) {
      console.log('Login successful');
    }).fail(function(xhr, textStatus, errorThrown) {
      alert('Error: ' + xhr.responseText);
    });
  });
});

在 Flask 中设置 CORS

使用 Flask 的 Python 后端代码

# Python (Flask) backend script
from flask import Flask, request, jsonify
from flask_cors import CORS

app = Flask(__name__)
CORS(app, supports_credentials=True)

@app.route('/login', methods=['POST'])
def login():
    data = request.get_json()
    username = data.get('username')
    password = data.get('password')

    if username == 'user' and password == 'pass':
        return jsonify({'message': 'Login successful'}), 200
    else:
        return jsonify({'message': 'Invalid credentials'}), 401

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000)

为什么 CORS 问题发生在浏览器中而不是 Postman 中

了解跨源资源共享 (CORS) 的一个重要方面是浏览器为保护用户而实施的安全机制。浏览器强制执行同源策略,该策略可防止网页向与提供该网页的域不同的域发出请求。这是一种安全措施,旨在防止恶意网站通过 JavaScript 访问其他网站上的敏感信息。当您从浏览器发出 XMLHttpRequest 或获取请求时,它会检查 'Access-Control-Allow-Origin' 来自服务器的响应中的标头。如果此标头不存在或不允许请求源,浏览器将阻止该请求,从而导致 CORS 错误。

另一方面,Postman 不是浏览器,而是测试 API 的工具。它不强制执行同源策略,因为它不在浏览器环境中运行。因此,它不执行相同的安全检查,并允许不受限制地向任何域发出请求。这就是为什么使用 Postman 发出相同请求时不会遇到 CORS 问题的原因。了解这种差异对于开发人员有效排查和解决 CORS 相关问题至关重要。通过配置服务器以包含适当的 CORS 标头,您可以确保您的 Web 应用程序可以安全且无错误地与外部 API 进行通信。

关于 CORS 和 JavaScript 的常见问题和解答

  1. 什么是 CORS?
  2. CORS 代表跨源资源共享,这是一种机制,允许从资源来源域之外的另一个域请求网页上的受限资源。
  3. 为什么浏览器强制执行同源策略?
  4. 强制执行同源策略是为了保护用户数据并防止恶意网站通过 JavaScript 访问其他域的敏感信息。
  5. 为什么 Postman 不强制实施 CORS?
  6. Postman 不强制实施 CORS,因为它不是浏览器,也不在浏览器环境中运行,因此不需要遵守同源策略。
  7. 如何解决 Web 应用程序中的 CORS 错误?
  8. 要解决 CORS 错误,请将服务器配置为包含适当的 'Access-Control-Allow-Origin' 响应中的标头,允许请求源。
  9. 什么是 'Access-Control-Allow-Origin' 标头做什么?
  10. 'Access-Control-Allow-Origin' header 指定允许哪些源访问资源,从而启用跨源请求。
  11. 目的是什么 withCredentials 在 XMLHttpRequest 中?
  12. withCredentials 属性指示是否应使用 cookie 或授权标头等凭据发出跨站点访问控制请求。
  13. 为什么我会收到 CORS 错误,即使我的服务器包含 'Access-Control-Allow-Origin' 标头?
  14. 如果其他必需的 CORS 标头(例如 'Access-Control-Allow-Methods' 或者 'Access-Control-Allow-Headers'、 缺失或配置不正确。
  15. 我可以在浏览器中禁用 CORS 吗?
  16. 不建议在浏览器中禁用 CORS,因为这会损害安全性。相反,配置您的服务器以正确处理 CORS。
  17. CORS 中的预检请求是什么?
  18. 预检请求是浏览器使用 OPTIONS 方法发出的初始请求,以确定实际请求是否可以安全发送。它检查服务器上所需的 CORS 标头。

结束讨论

了解 CORS 和同源策略的细微差别对于 Web 开发人员至关重要。虽然浏览器强制执行严格的安全措施来保护用户,但 Postman 等工具却绕过了这些限制,使测试 API 变得更加容易。通过使用必要的 CORS 标头正确配置后端,开发人员可以确保前端和后端之间顺利、安全的通信。解决 CORS 问题对于创建功能齐全且用户友好的 Web 应用程序至关重要。