简体   繁体   English

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

[英]No 'Access-Control-Allow-Origin' header is present on the requested resource Flask+JQuery

I'm trying to do a straightforward authentication with some JQuery on the client side and a python with flask for the server. 我正在尝试使用客户端上的一些JQuery和服务器的带有flask的python进行简单的身份验证。 The idea is that I give the username and the password in the input field, I click the connect button, JQuery get the username and the password, parse them in json and send them with a post method to the server at localhost/auth, the server check if the username and the password exist in the database, if it doesn't he return a fail else success (like I said, straightforward). 我的想法是在输入字段中输入用户名和密码,单击连接按钮,JQuery获取用户名和密码,将其解析为json并通过post方法将其发送到localhost / auth的服务器,服务器检查数据库中是否存在用户名和密码,如果不存在,则返回失败,否则返回成功(如我所说,很简单)。 But when I do it I get the infamous error 但是当我这样做时,我得到了臭名昭著的错误

Response to preflight request doesn't pass access control check: 
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'null' is therefore not allowed access. The response
had HTTP status code 404.

So the problem seems to come from the header Access-Control-Allow-Origin on the server side but the server doesn't seem to even get the request (in the flask console I don't get an "OPTION" method or anything) and more than that I did set the header. 因此,问题似乎出在服务器端的标头Access-Control-Allow-Origin上,但是服务器似乎甚至没有收到请求(在烧瓶控制台中,我没有“ OPTION”方法或其他任何东西)不仅如此,我还设置了标题。 Here is my javascript + html: 这是我的javascript + html:

<!DOCTYPE html>
  <html>
  <script src="jquery-3.1.1.min.js"></script>
  <head>
    <meta charset="utf-8">
    <title>DIMAC</title>
  </head>
  <body>
  <script>
  $(function() {
    $('#connect').on('click',function(){
      username = $('#user').val()
      password = $('#pass').val()
      if(username != "" && password != ""){
          $.ajax({
              url: 'http://127.0.0.1/auth',
              type: "POST",
              dataType:"application/json; charset=utf-8",
              headers: {'Access-Control-Allow-Origin':'*'},
              data: JSON.stringify({
                  username: username,
                  password: password
              }),
              xhrFields: {withCredentials: true},
              processData: false,
              crossDomain: true,
              success: function () {
                  alert("success");
              },
              error: function (xhr, ajaxOptions, thrownError) {
                  alert(ajaxOptions);
                  alert(thrownError);
              },
        });
      }
    })

      })
  </script>
      <h1 id="title">Test</h1>
  <div>
      <label> Username</label>
      <input id="user" type="text"/>
      <label> Password</label>
      <input id="pass"type="password"/>
  <button id="connect" name"connect"> Connect </button>
  </div>
  </body>

I put the header access control allow origin = * here too for the sake of it. 为此,我也将标头访问控制允许origin = *放在了这里。

And for my python: 对于我的python:

from flask import Flask, request, make_response
from flask_cors import CORS, cross_origin
import json
from source import database_manager as database
app = Flask(__name__)
cors = CORS(app, resources={r"/api/*": {"origins": "http://localhost/auth"}})
app.debug = True

@app.route('/auth', methods=['POST'])
def auth_client():
    data = request.get_json()
    # Init the database
    db = database.DatabaseManager("127.0.0.1", "5432", "postgres")
    print(data)
    # Get the Users with this name and this password (so one and one only if the credentials are right)
    user = db.select('SELECT * FROM Users WHERE usr_name = %(usr_name)s and     usr_password = %(usr_password)s;', {
        'usr_name': data["username"],
        'usr_password': data["password"]
    })
    db.close()
    # If the db didn't return one and only one user
    if len(user) != 1:
        resp = response("Invalid credentials", 401)
        # resp.headers['WWW-Authenticate'] = 'Basic realm="Credentials required"'
        # Debug
        print("Wrong")
        return resp

    else:
        resp = make_response(json.dumps("Success"))
        resp.status_code = 201
        resp.headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1/auth'
        resp.headers['Access-Control-Allow-Methods'] = '*'
        resp.headers['Access-Control-Allow-Domain'] = '*'
        resp.headers['Access-Control-Allow-Credentials'] = True
        # Debug
        print("Right")
        return resp

The db thingy I use call the database with psycopg2, it's legit if you're asking. 我使用的数据库问题是用psycopg2调用数据库,如果您要问的话,这是合法的。 I also try CORS(app) But this doesn't work either. 我也尝试使用CORS(app),但这也不起作用。

Edit: 编辑:

Following Maresh advice I now only talk about localhost in all of my code, I also give the port in my ajax part ( url is now http://localhost:5000/auth ) and so I get a new error (so it appear that I'm going forward here): 遵循Maresh的建议,我现在仅在所有代码中谈论localhost,我还在我的ajax部分中提供了端口(URL现在为http:// localhost:5000 / auth ),所以我得到了一个新错误(所以看起来我要在这里前进):

Response to preflight request doesn't pass access control check: No
'Access-Control-Allow-Origin' header is present on the requested 
resource. Origin 'null' is therefore not allowed access.

And my server get an OPTION request now so it's almost working! 我的服务器现在收到一个OPTION请求,因此几乎可以正常工作!

The browser does a preflight HTTP OPTIONS call before making the post call so you also need to return the CORS policy there. 浏览器在进行后期调用之前会进行预检 HTTP OPTIONS调用,因此您还需要在此处返回CORS策略。

I tend to prefer leaving the CORS handling to the http server ( nginx /apache), it gives more flexibility to the people deploying your app. 我倾向于将CORS处理留给http服务器( nginx / apache),它为部署您的应用程序的人员提供了更大的灵活性。

eg: you don't need to change the code when changing domain. 例如:更改域时无需更改代码。

Edit: In your case I see several mistake, first you define the origin as localhost: 编辑:在您的情况下,我看到几个错误,首先将源定义为localhost:

cors = CORS(app, resources={r"/api/*": {"origins": "http://localhost/auth"}})

Then you use 127.0.0.1: 然后您使用127.0.0.1:

resp.headers['Access-Control-Allow-Origin'] = 'http://127.0.0.1/auth'

So which one do you want? 那你要哪一个呢? localhost or 127.0.0.1? 本地主机还是127.0.0.1? It's about domain here so it's not the same thing. 这是关于域的,所以不是一回事。 For the rest of the answer I'll assume you want localhost 对于其余的答案,我假设您想要localhost

Both lines have the mistakes of adding the path /auth you only want the protocol://domain optionally adding the :portnumber if it's non-standard. 这两行都有添加路径/auth的错误,如果不标准,则只希望protocol://domain可选地添加:portnumber

Additionally you don't need the CORS plugin if you add the header manually. 另外,如果您手动添加标题,则不需要CORS插件。

And finally the error that you see is a 404 so it means that your ajax call URL is wrong, or your server is not running on your localhost. 最后,您看到的错误是404,这意味着您的Ajax调用URL错误,或者您的服务器未在本地主机上运行。 Since it doesn't go through your code the cors headers are never set. 由于它不会遍历您的代码,因此永远不会设置cors标头。

The response had HTTP status code 404 . 响应具有HTTP状态代码404

So one dirty quickfix would be: 因此,一个肮脏的Quickfix将是:

cors = CORS(app, resources={r"/api/*": {"origins": "http://localhost"}})
...
@app.route('/auth', methods=['POST'])
def auth_client():
        ...
        resp.headers['Access-Control-Allow-Origin'] = 'http://localhost'
        resp.headers['Access-Control-Allow-Methods'] = '*'
        resp.headers['Access-Control-Allow-Domain'] = '*'
        resp.headers['Access-Control-Allow-Credentials'] = True
        # Debug
        print("Right")
        return resp

@app.route('/auth', methods=['OPTIONS'])
    def preflight():
            resp = make_response("OK")
            resp.status_code = 201
            resp.headers['Access-Control-Allow-Origin'] = 'http://localhost'
            resp.headers['Access-Control-Allow-Methods'] = '*'
            resp.headers['Access-Control-Allow-Domain'] = '*'
            resp.headers['Access-Control-Allow-Credentials'] = True
            # Debug
            print("Right")
            return resp

And in the ajax call also use: localhost And serve your frontend code from localhost 并且在ajax调用中还使用: localhost并从localhost提供您的前端代码

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 带有Access-Control-Allow-Origin标头的Jquery + CORS +基本身份验证:所请求的资源上不存在“ Access-Control-Allow-Origin”标头 - Jquery + CORS+ Basic Auth with Access-Control-Allow-Origin header: No 'Access-Control-Allow-Origin' header is present on the requested resource Javascript-所请求的资源上没有“ Access-Control-Allow-Origin”标头 - Javascript - No 'Access-Control-Allow-Origin' header is present on the requested resource 请求的资源上不存在“Access-Control-Allow-Origin”标头 - No 'Access-Control-Allow-Origin' header is present on the requested resource 角度4-所请求的资源上没有“ Access-Control-Allow-Origin”标头 - Angular 4 - No 'Access-Control-Allow-Origin' header is present on the requested resource NodeJ在所请求的资源上不存在“ Access-Control-Allow-Origin”标头 - NodeJs No 'Access-Control-Allow-Origin' header is present on the requested resource Access-Control-Allow-Origin header 存在于请求的资源上 - Access-Control-Allow-Origin header is present on the requested resource 从 Flask API 获取“请求的资源上不存在‘Access-Control-Allow-Origin’标头” - Getting "No 'Access-Control-Allow-Origin' header is present on the requested resource" from Flask API 请求的资源 .htaccess 上不存在 Access-Control-Allow-Origin 标头 - No Access-Control-Allow-Origin header is present on the requested resource .htaccess XMLHttpRequest请求的资源上没有“Access-Control-Allow-Origin”标头 - XMLHttpRequest No 'Access-Control-Allow-Origin' header is present on the requested resource 请求的资源上不存在Access-Control-Allow-Origin标头 - Access-Control-Allow-Origin header is not present on the requested resource
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM