javascript - 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.
解决方案
尝试使用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!"
你现在应该访问它。
推荐阅读
- apache - Apache:如何打开对目录及其内容的读取权限,提供目录列表,但不提供写入权限?
- python - 如何轮询 Azure 服务总线队列中的消息?
- python - 在 Python 中 Base64 解码文本文件到 Bin 文件
- javascript - 单选按钮检查不适用于 jquery
- javascript - 使用 Lodash 将最后一个树节点合并到一个数组中
- deno - deno 是否有任何替代 ajv(json-schema 验证器)?
- css - 如何在 SVG 中缩放重复模式?
- tensorflow - Spark Dataframe 到 Tensorflow 数据集(tf.data API)
- javascript - 在表单中使用 jquery 操作
- php - 使用模态选择产品 - laravel