烧瓶 api 端点使用邮递员返回正确的响应,但不使用浏览器(chrome)

Posted

技术标签:

【中文标题】烧瓶 api 端点使用邮递员返回正确的响应,但不使用浏览器(chrome)【英文标题】:The flask api endpoint returns the correct response with postman but not with the browser(chrome) 【发布时间】:2020-11-29 22:13:09 【问题描述】:

第一个文件是包含flask api的app.py

from flask import Flask, request, jsonify, make_response
from werkzeug.utils import cached_property
from flask_restx import Api, Resource, fields
from flask_cors import CORS
import numpy as np
import sys
import pickle

flask_app = Flask(__name__)
app = Api(app = flask_app, 
          version = "1.0", 
          title = "Boston House Classification", 
          description = "Predict house price")

CORS(flask_app)

name_space = app.namespace('prediction', description='Prediction APIs')

model = app.model('Prediction params', 
                  'x1': fields.Float(required = True, 
                                               description="x1", 
                                               help="salary cannot be blank"),
                  'x2': fields.Float(required = True, 
                                               description="x2", 
                                               help="age cannot be blank"),
                  )
filename = "finalized_model.sav"
classifier = pickle.load(open(filename, 'rb'))

@name_space.route("/")
class MainClassFirst(Resource):

    def get(self):
        response = "hello"
        return make_response(jsonify("result":response))

@name_space.route("/predict/")
class MainClass(Resource):

    # def options(self):
    #   response = make_response()
    #   response.headers.add("Access-Control-Allow-Origin", "*")
    #   response.headers.add('Access-Control-Allow-Headers', "*")
    #   response.headers.add('Access-Control-Allow-Methods', "*")
    #   return response

    @app.expect(model)      
    
    def post(self): 
        formData = request.json
        data = [val for val in formData.values()]
        print(data, file = sys.stderr)
        newarr = np.array(data).reshape(1,-1).astype(np.float)
        
        prediction = classifier.predict(newarr)
        res = str(prediction[0])
        
        response = jsonify(
            "statusCode": 200,
            "status": "Prediction made",
            "result": res
            )
        response.headers.add('Access-Control-Allow-Origin', '*')
        return response

在这里,我尝试使用 flask_cors 中的 CORS,并尝试使用 options 方法自己处理它(在代码中进行了注释)。下面给出了进行调用的 react 应用程序的 App.js 文件。

import React,  Component  from 'react';

class FormContainer extends Component 
  
  constructor (props) 
    super(props);
    
      this.state = 
          formControls: 
              x1: 
                value: ''
              ,
              x2: 
                value: ''
              ,
              submit: 
                value: ''
              ,
              answer: 
                value: ''
              
          
      
    
  
  
  changeHandler = event => 
      
      const name = event.target.name;
      const value = event.target.value;
    
      this.setState(
        formControls: 
            ...this.state.formControls,
            [name]: 
            ...this.state.formControls[name],
            value
          
        
      );
  

  submitHandler = event => 
      
    const requestOptions = 
      method: 'POST',
      headers:  'Content-Type': 'application/json' ,
      body: JSON.stringify( x1: this.state.formControls.x1.value,
        x2: this.state.formControls.x2.value, )
  ;
  fetch('http://localhost:5000/prediction/predict/', requestOptions)
      .then(async response => 
          const data = await response.json();

          // check for error response
          if (!response.ok) 
              // get error message from body or default to response status
              const error = (data && data.message) || response.status;
              console.log(error)
              return Promise.reject(error);
          

          
          console.log(response)
      )
      .catch(error => 
        
          console.error('There was an error!', error);
      );


  
   render() 
      return (
          
          <form>
  <div className="form-group row">
    <label htmlFor="inputEmail3" className="col-sm-2 col-form-label">x1</label>
    <div className="col-sm-10">
    <input type="text" 
                     name="x1" 
                     value=this.state.formControls.x1.value 
                     onChange=this.changeHandler 
              />
    </div>
  </div>
  <div className="form-group row">
    <label htmlFor="inputPassword3" className="col-sm-2 col-form-label">x2</label>
    <div className="col-sm-10">
    <input type="text" 
                     name="x2" 
                     value=this.state.formControls.x2.value 
                     onChange=this.changeHandler 
              />
    </div>
  </div>

  <input className="form-control" type="text" placeholder="Readonly input here..." name="answer" 
                     defaultValue=this.state.formControls.answer.value 
                      readOnly></input>
  
  <div className="form-group row">
    <div className="col-sm-10">
      <button type="submit" className="btn btn-primary" name="submit" 
                     value=this.state.formControls.submit.value 
                     onClick=this.submitHandler>Submit</button>
    </div>
  </div>
</form>      
      );
  




export default FormContainer;

The networks tab output

flask terminal output

我是新来的反应和烧瓶。 一点帮助将不胜感激。

【问题讨论】:

【参考方案1】:

您必须为您的 Flask 应用程序设置 CORS 以接受来自 localhost 的 ajax 调用:

https://flask-cors.readthedocs.io/en/latest/

【讨论】:

我已经做了pip install -U flask-cors。这就是为什么我可以导入 CORS 。我看不到更多设置步骤。

以上是关于烧瓶 api 端点使用邮递员返回正确的响应,但不使用浏览器(chrome)的主要内容,如果未能解决你的问题,请参考以下文章

烧瓶根据邮递员的邮寄请求返回 400

尝试从客户端登录到后端烧瓶 api 时出现 401 UNAUTHORIZED 状态

Laravel api在邮递员中返回值,但在Vue js中返回空数组

如何在不使用请求的情况下直接从代码调用烧瓶端点

构建/发布 web .net 核心 api:我无法访问他们从邮递员返回 500 的任何端点

使用烧瓶返回布尔作为POST响应[重复]