首页 > 解决方案 > Javascript XMLHttpRequest - 已被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头

问题描述

我在这里找到了一个引用相同问题的帖子:

Javascript - 请求的资源上不存在“Access-Control-Allow-Origin”标头

我试图实施该线程中列出的解决方案,但无济于事。

我正在尝试学习如何通过 Javascript 将 XMLHttpRequests 发送到 Flask 服务器。

Python代码:

from flask import Flask, render_template
from datetime import timedelta
from flask import make_response, request, current_app
from functools import update_wrapper


app = Flask(__name__)

# Decorator listed in previous post

def crossdomain(origin=None, methods=None, headers=None, max_age=21600,
            attach_to_all=True, automatic_options=True):
    if methods is not None:
        methods = ', '.join(sorted(x.upper() for x in methods))
    if headers is not None and not isinstance(headers, list):
        headers = ', '.join(x.upper() for x in headers)
    if not isinstance(origin, list):
        origin = ', '.join(origin)
    if isinstance(max_age, timedelta):
        max_age = max_age.total_seconds()

    def get_methods():
        """ Determines which methods are allowed
        """
        if methods is not None:
            return methods

        options_resp = current_app.make_default_options_response()
        return options_resp.headers['allow']

    def decorator(f):
        """The decorator function
        """
        def wrapped_function(*args, **kwargs):
            """Caries out the actual cross domain code
            """
            if automatic_options and request.method == 'OPTIONS':
                resp = current_app.make_default_options_response()
            else:
                resp = make_response(f(*args, **kwargs))
            if not attach_to_all and request.method != 'OPTIONS':
                return resp

            h = resp.headers
            h['Access-Control-Allow-Origin'] = origin
            h['Access-Control-Allow-Methods'] = get_methods()
            h['Access-Control-Max-Age'] = str(max_age)
            h['Access-Control-Allow-Credentials'] = 'true'
            h['Access-Control-Allow-Headers'] = \
                "Origin, X-Requested-With, Content-Type, Accept, Authorization"
            if headers is not None:
                h['Access-Control-Allow-Headers'] = headers
            return resp

        f.provide_automatic_options = False
        return update_wrapper(wrapped_function, f)
    return decorator



texts = ["Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aliquam tortor mauris, maximus semper volutpat vitae, varius placerat dui. Nunc consequat dictum est, at vestibulum est hendrerit at. Mauris suscipit neque ultrices nisl interdum accumsan. Sed euismod, ligula eget tristique semper, lectus est pellentesque dui, sit amet rhoncus leo mi nec orci. Curabitur hendrerit, est in ultricies interdum, lacus lacus aliquam mauris, vel vestibulum magna nisl id arcu. Cras luctus tellus ac convallis venenatis. Cras consequat tempor tincidunt. Proin ultricies purus mauris, non tempor turpis mollis id. Nam iaculis risus mauris, quis ornare neque semper vel.",
        "Praesent euismod auctor quam, id congue tellus malesuada vitae. Ut sed lacinia quam. Sed vitae mattis metus, vel gravida ante. Praesent tincidunt nulla non sapien tincidunt, vitae semper diam faucibus. Nulla venenatis tincidunt efficitur. Integer justo nunc, egestas eget dignissim dignissim, fermentum ac sapien. Suspendisse non libero facilisis, dictum nunc ut, tincidunt diam.",
        "Morbi imperdiet nunc ac quam hendrerit faucibus. Morbi viverra justo est, ut bibendum lacus vehicula at. Fusce eget risus arcu. Quisque dictum porttitor nisl, eget condimentum leo mollis sed. Proin justo nisl, lacinia id erat in, suscipit ultrices nisi. Suspendisse placerat nulla at volutpat interdum. In porttitor condimentum est nec ultricies. Donec nec mollis neque, id dapibus sem."]

@app.route("/", methods=['GET', 'OPTIONS'])
@crossdomain(origin='*')
def index():

    return render_template("index.html")

@app.route("/first")
def first():
    return texts[0]

@app.route("/second")
def second():
    return texts[1]

@app.route("/third")
def third():
    return texts[2]

Javascript/HTML(index.html):

<!DOCTYPE html>
<html>
<head>
  <title>My Document</title>
  <script>

    document.addEventListener('DOMContentLoaded', ()=>{
      load('/first');

      document.querySelectorAll(".nav-link").forEach(function(link){
        link.onclick = () =>{
          load(link.dataset.page);
          return false;
        }
      });
    });

    function load(name){
      const request = new XMLHttpRequest();
      request.open('GET', `/${name}`);
      request.onload = () =>{
        const response = request.responseText;
        document.querySelector('#body').innerHTML = response;
      };
      request.send();
    }
  </script>
</head>
<body>
  <ul id="nav">
    <li><a href="" class="nav-link" data-page="first">First Page</a></li>
    <li><a href="" class="nav-link" data-page="second">Second Page</a></li>
    <li><a href="" class="nav-link" data-page="third">Third Page</a></li>
  </ul>
  <hr>
  <div id="#body">
  </div>
  <body>
</html>

尽管实现了装饰器,但我仍然遇到同样的错误。任何人都可以帮忙吗?

确切的错误:

(index):1 Access to XMLHttpRequest at 'http://first/' from origin 'http://127.0.0.1:5000'
  has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is 
  present on the requested resource.

标签: javascriptpythonflask

解决方案


尝试使用flask-cors,您可以通过以下方式轻松安装它:

pip install -U flask-cors

flask-cors的一个例子

from flask import Flask
from flask_cors import CORS

app = Flask(__name__)
CORS(app)

@app.route("/")
def helloWorld():
  return "Hello, cross-origin-world!"

你现在应该访问它。


推荐阅读