postman可以通的请求,前端通不了(前端添加Content-type,后端收不到请求)

接口完成之后,自己使用postman测试了一下,没有问题;

可是在和小组前端调试接口的时候,他却说访问不了;

信息如下:(我自己写的一个打印请求信息的拦截器)

发现报错信息是:

 Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported
也就是说发送过来的内容格式为 “application/x-www-form-urlencoded;charset=UTF-8”,这个内容格式后端不支持;

主要是因为我的后端使用的是@RequestBody注解接收的参数

这个注解需要“application/json”格式的数据;

让后前端就加了一个

headers: {
                        'Content-Type': 'application/json;charset=UTF-8'
                    }

可是此时他使用的框架却报错了

Network Error
AxiosError: Network Error
    at XMLHttpRequest.handleError (webpack-internal:///.de_modules/axiosb/adapters/xhr.js:160:14)

并且我后端的信息如下:

请求方式为OPTION;(可是他发送的是Post)

我也看不懂

去问了一下chatgpt

也去搜了许多相关的博文,

后面发现将Content-Type设置成application/json会受到同源政策的限制。就会会先发送一个option请求嗅探服务器是否具有应答的能力,然后才会发送真正的请求。

此时关键的就来了,

"Access-Control-Allow-Headers"响应头告诉浏览器服务器允许的额外请求头,以便浏览器可以继续发送实际的跨域请求。

也就是说后端需要设置一个"Access-Control-Allow-Headers"让浏览器发送真实的跨域请求(这里设置了headers的请求);

代码如下:添加一个拦截器

package com.kzj.common.filter;

import javax.servlet.*;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@WebFilter//需要启动类开启@ServletComponentScan才会生效
public class MyAddCrossOrigin implements Filter {
    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        HttpServletResponse response=(HttpServletResponse)servletResponse;
        //允许来自任何源的跨域请求
        response.setHeader("Access-Control-Allow-Origin", "*");
        //设置允许的请求头为"X-Requested-With"和"Content-Type"。这样设置允许浏览器发送带有这些请求头的跨域请求。
        response.setHeader("Access-Control-Allow-Headers","X-Requested-With, Content-Type");
        //指定了服务器允许的跨域请求方法
        response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE");
        filterChain.doFilter(servletRequest,response);
    }
}

  1. response.setHeader("Access-Control-Allow-Origin", "*");
    这一行设置了"Access-Control-Allow-Origin"响应头,将其值设置为"",表示允许来自任何源的跨域请求。使用""表示允许所有源进行访问。这可能存在一定的安全风险,因为允许所有源的访问可能导致潜在的安全问题。在生产环境中,应该根据实际需求将"*"替换为允许的具体源。

  2. response.setHeader("Access-Control-Allow-Headers", "X-Requested-With, Content-Type");
    这一行设置了"Access-Control-Allow-Headers"响应头,指定了服务器允许接收的额外请求头。在这里,设置允许的请求头为"X-Requested-With"和"Content-Type"。这样设置允许浏览器发送带有这些请求头的跨域请求。

  3. response.setHeader("Access-Control-Allow-Methods", "POST,GET,PUT,DELETE");
    这一行设置了"Access-Control-Allow-Methods"响应头,指定了服务器允许的跨域请求方法。在这里,设置允许的请求方法为POST、GET、PUT和DELETE。这样设置允许浏览器使用这些方法发起跨域请求。

通过这些设置,服务器告知浏览器允许来自任意源的跨域请求,并且允许接收特定的请求头和请求方法。这样可以解决浏览器中的跨域限制,使前端代码能够与后端进行跨域通信。

修改后后端就可以正常的收到请求了

<think>好的,我现在需要解决用户的问题:在Flask中使用request.values.get方法无法获取到前端过GET请求传递的参数。用户提到前端使用GET请求,但后端用request.values.get拿不到参数。我需要分析可能的原因,并提供解决方案。 首先,我得回忆Flask中处理请求参数的不同方法。根据用户提供的引用,比如引用[2]和[3],Flask有request.args用于GET参数,request.form用于POST表单数据,而request.values合并两者。但用户用了request.values.get,按理说应该可以获取GET参数,因为request.values是CombinedMultiDict,包含args和form的数据。那为什么获取不到呢? 可能的原因有几个: 1. **前端传参方式错误**:比如参数没有正确附加在URL的查询字符串中。例如,正确的GET请求应该是http://example.com/route?key=value,如果前端没有正确拼接参数,后端自然无法获取。 2. **后端路由配置问题**:可能路由没有允许GET方法,或者参数被路由规则截获了。例如,如果路由定义的是@app.route('/example'),但前端请求的是/example/,可能会导致问题。或者路由中有变量捕获,比如@app.route('/example/<name>'),这时参数可能被路由变量捕获,而不是作为查询参数。 3. **参数名拼写不一致**:前端传递的参数名和后端获取时使用的键名不一致,比如前端传的是'user',而后端用'username'获取,这当然拿不到。 4. **使用request.values的时机或方式错误**:例如,在POST请求中同时有表单数据和查询参数,但用户错误地使用了GET方法,或者Content-Type设置不正确,导致参数没有被正确解析。 5. **浏览器缓存或前端代码问题**:有时候前端可能没有正确发送参数,比如在Ajax请求中忘记添加参数,或者参数被错误地编码。 接下来,我需要逐步分析这些可能性,并提供对应的解决方案。比如,检查前端是否真的发送了GET请求,参数是否在URL中可见,或者用工具如Postman测试请求是否正确。同时,查看后端路由设置是否正确,参数名是否匹配,以及是否在正确的请求方法中获取参数。 根据引用[4],在GET请求中,参数可以过request.args和request.values获取。所以用户的问题可能出在参数传递方式或路由配置上。可能需要用户检查URL中的查询字符串是否正确,或者是否存在其他中间件干扰。 另外,建议用户打印request.values的内容,或者检查请求的URL是否确实带有参数。例如,在Flask中使用print(request.values.to_dict())来查看所有参数,确认是否包含预期的键值对。 总结可能的解决步骤: 1. 确认前端发送的是GET请求,且参数正确附加在URL后。 2. 检查后端路由是否允许GET方法。 3. 核对参数名称是否一致。 4. 使用调试工具查看请求详情。 5. 在Flask中打印request.values以确认参数是否存在。 最后,还需要提醒用户关于Content-Type的问题,虽然GET请求常不需要设置,但如果前端错误地设置了Content-Type,可能会影响参数的解析。不过根据引用[4],GET请求的参数获取不受Content-Type影响,因为参数在URL中。</think>针对Flask中使用`request.values.get`无法获取GET请求参数的问题,以下是逐步排查与解决方案: --- ### **1. 确认前端请求格式正确** GET请求参数需以**查询字符串**形式附加在URL末尾,格式为`?key1=value1&key2=value2`。例如: ```javascript // 前端示例:发送GET请求 fetch('/api/data?name=John&age=25', { method: 'GET' }) .then(response => response.text()) ``` **检查点**: - 参数是否拼接到URL中。 - 特殊字符(如空格、符号)是否经过URL编码(使用`encodeURIComponent`)[^2]。 --- ### **2. 验证Flask路由配置** 确保路由允许GET方法且未截获参数: ```python from flask import Flask, request app = Flask(__name__) # 正确配置:允许GET方法且未定义动态路由参数 @app.route('/api/data', methods=['GET']) # 明确声明methods=['GET'] def get_data(): name = request.values.get('name') age = request.values.get('age') return f"Received: {name}, {age}" ``` **常见错误**: - 路由中使用了动态参数(如`/api/data/<id>`),导致查询参数被忽略。 - 未声明`methods=['GET']`,默认仅允许GET,但若其他方法干扰需显式声明[^3]。 --- ### **3. 核对参数名称一致性** 确保前后端参数名称**完全匹配**(区分大小写): ```python # 后端获取参数的键名需与前端一致 request.values.get('username') # 前端必须传递 'username' 而非 'user' ``` --- ### **4. 使用调试工具验证参数** 过打印`request.values`或`request.args`检查实际接收的参数: ```python @app.route('/api/data', methods=['GET']) def get_data(): print("Received values:", request.values.to_dict()) # 输出所有参数 print("Received args:", request.args.to_dict()) # 仅GET参数 return "Check console logs" ``` **输出示例**: ```plaintext Received values: {'name': 'John', 'age': '25'} Received args: {'name': 'John', 'age': '25'} ``` 若输出为空,则前端未正确发送参数[^4]。 --- ### **5. 使用Postman或浏览器直接测试** 手动构造URL测试后端: ``` http://localhost:5000/api/data?name=John&age=25 ``` 若此时能获取参数,则问题出在前端代码;否则需检查Flask配置。 --- ### **6. 检查请求头与编码问题** 虽然GET请求常无需设置`Content-Type`,但确保前端未错误添加: ```javascript // 错误示例:GET请求设置Content-Type常无关) headers: { 'Content-Type': 'application/json' } // 可能导致解析异常 ``` GET请求参数应仅过URL传递,而非请求体[^4]。 --- ### **总结解决方案** 1. 前端确保参数拼接在URL查询字符串中。 2. 后端路由正确配置GET方法且无冲突。 3. 过打印`request.values`验证参数接收。 4. 使用工具直接测试URL排除前端问题。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值