AJAX、CORS、jQuery、表单提交

AJAX、jQuery、CORS

需求

自己做了个问答系统,客户端用户在前端页面提出问题,问题需要提交到后台(不同域的服务端,不同域:域名,端口等有一个不同就是跨域问题),后台给出问题答案后返回前端进行异步刷新(ajax)。

遇到的问题

  • 如何实现局部刷新(异步刷新

    • ajax 可以实现异步传输数据、局部刷新
  • 在上个问题基础上遇到了,ajax跨域问题

    • 跨域常见的方法有jsonp,CORS技术
    • jsonp只能发送GET请求,CORS可以发送GET或者POST等
    • CORS主要是在服务端配置允许请求的域信息(我的服务端采用的flask,底层是WSGI服务协议)
  • 前端 form提交时数据没有提交成功

    • 注意看浏览器控制台是否报错,最开始报错‘$.ajax func is not found’,是因为我引入的jQuery是slim版本,其中的ajax被移除了,故需要重新引入包含ajax的jquery.js文件
    • 包问题解决后发现form表单数据还是提交不成功,经过各种摸索,试验,最后发现普通的 按钮,默认的type=‘submit’,会自动提交数据,导致页面刷新(相当于自己编写的ajax函数没有得到请求结果就被刷新覆盖了),而在form外部是可以提交成功的,但是这样我们就无法获得表单的提交信息了。解决:input 、button 想要在form内部顺利提交表单(能够执行ajax并返回结果,不被强制刷新页面),都需显示指定type=‘button’
  • 浏览器缓存问题
    以link、script 文件方式引入的文件修改后要清楚浏览器缓存才能看到效果。否则会出现代码都对了,但是达不到效果,也不知到问题出在哪里的现象,这个问题很容易被忽视。

  • 局部更改 带有!import 的css属性问题

    • js有个 ‘cssText’ 属性,存储了当前元素的所有css值,我们可以通过在这个cssText基础上增加、覆盖值来更改
$("#card-header").text("查询成功").css("cssText","background-color:#28a745 !important;color:#fff;");

前端

method one:
<script>
    $(document).on("click","#btn",get_answer); //绑定按钮
    function get_answer(){
        var start_time = get_time();
        var question = $("#question").get(0).value;

        if (question == ''){
            return false;
        }

       $.ajax({
            type:'post',
            data:{"question":question},
            url:'http://127.0.0.1:5000/',
            async:true,
            dataType:"json",
            // xhrFields: {withCredentials: true}, //加这个报错,暂时不知道为啥???
            success:function (data,status) {
                console.log("status : " + status);
                console.log("answer : " + data['answer']);
                console.log("valid answer : " + data['valid_answer'])

                $("#answer").text(data['answer']);
                var time_consume = get_time() - start_time;
                var valid_answer = data['valid_answer'];

                if (valid_answer == "true"){
                    console.log("valid answer true comes")
                    $("#card-header").text("查询成功").css("cssText","background-color:#28a745 !important;color:#fff;");
                }
                else {
                    console.log("valid answer false comes");
                    $("#card-header").text("查询失败").css("cssText","background-color:#dc3545 !important;color:#fff;");
                }

                $("#time_consume").text("用时: " + time_format(time_consume) + "s");


                console.log("花费时间 : " + time_consume.toString());
            },
           error:function(){
                console.log("Request error.")
                var err_msg = "请求服务器出错,请稍后尝试。"
                $("#answer").text(err_msg);
            }
        })
    }

function get_time() {
     return new Date().getTime();
}

function time_format(time) {
    var seconds = time / 1000;
    return seconds.toFixed(2); // 保留2位小数
}
</script>

<form action="" class="flex justify-content-center align-items-center">
     <div class="input-group">
         <input type="text" class="form-control" placeholder="请输入问题" id="question">
         <button type="button" id="btn" class="btn btn-secondary" onclick="get_answer()">
             <span class="fa fa-search"></span>
         </button>
     </div>
</form>
method two:
// get_answer 函数 同上,可以把onclick直接写在input里面。实现绑定
<form action="" class="flex justify-content-center align-items-center">
     <div class="input-group">
         <input type="text" class="form-control" placeholder="请输入问题" id="question">
            <input type="button" class="btn btn-secondary" onclick="get_answer()">
                 <span class="fa fa-search"></span>
             </input>
     </div>
</form>

后端(基于Flask)

from flask import Flask,request,make_response,jsonify
from flask_cors import * # 解决ajax 跨域问题请求

app = Flask(__name__)
# r'/*' 是通配符,让本服务器所有的URL 都允许跨域请求
# CORS(app, resources=r'/*',supports_credentials=True) # supports_credentials=True 多加会报错,暂时不知道原因
CORS(app, resources=r'/*')

@app.route("/",methods=('GET', 'POST'))
def index():
    global handler

    if request.method == 'POST':
        print("get post request")
        question = request.form['question']
        answer = handler.question_answer_main(question)
        if answer == "非常抱歉,这个问题超出小医的能力范围!":
            valid_answer = "false"
        else:
            valid_answer = "true"

        result_text = {"statusCode": 200, "answer": answer,"valid_answer":valid_answer}

        response = make_response(jsonify(result_text)) # jsonify 返回json格式数据
        response.headers['Access-Control-Allow-Origin'] = '*'
        # response.headers['Access-Control-Allow-Credentials'] = 'true'
        response.headers['Access-Control-Allow-Methods'] = 'OPTIONS,HEAD,GET,POST'
        response.headers['Access-Control-Allow-Headers'] = 'x-requested-with'

        return response

    else:
        question = request.args.get('question')
        answer =  handler.question_answer_main(question)
    return answer

你可能感兴趣的:(前端)