配置
前端:Ajax 请求
后端:Servlet
浏览器:edge
踩坑问题
1.跨域问题
在服务器端已添加响应头
预检请求状态为200,但是post请求不通过
2.服务器处理问题
将JSON字符串传递到后端,使用request.getParameter(" ")方法提取不到数据。
解决方案
1.跨域问题
当ajax传出的数据类型为’application/json’(即JSON字符串类型
) 时,会附带提交预检请求
但如果传出的数据类型为对象,则不会提交预检请求,且会直接通过
抓包显示未提交预检请求,且post请求通过
所以问题原因在预检请求,下面我们看预检请求具体细节
我们看到响应表头中并未出现我们先前添加的Access-Control-Allow-Origin
,问题原因暂未找到,直接提供解决方法(较为暴力
) 。
使用edge中的插件CORS Unblock
其功能为:将更改浏览器收到的每个请求的“Access-Control-Allow-Origin”和“Access-Control-Allow-Methods”标头来绕过“XMLHttpRequest”和“fetch”拒绝。
也就是为我们自动添加标头,以解决标头添加失败问题。
启动插件后:
可见,预检请求的“Access-Control-Allow-Origin”和“Access-Control-Allow-Methods”标头被正确添加,问题解决(只适用于开发环境,并不算真正地解决问题,比较暴力
)。
2. 服务器处理问题
踩坑原因
当我向后端传入JSON字符串时,在后端中提取数据的代码为
当检查日志时,发现两个变量值均为NULL,因此,.getParameter(" ")
方法提取不出request对象中的数据。
经查询与试验,
- 当前端传出数据类型为对象时,
.getParameter(" ")
方法适用, - 当前端传出数据类型为JSON字符串类型时,需要使用
BufferedReader
来读取request对象,将其转化为字符串,再将JSON 字符串解析为 JSON 对象,从而使用.getString(" ")
方法提取数据
解决方案
// 从请求中获取 JSON 字符串
StringBuilder sb = new StringBuilder();
String line;
BufferedReader reader = request.getReader();
while ((line = reader.readLine()) != null) {
sb.append(line);
}
String jsonString = sb.toString();
// 将 JSON 字符串解析为 JSON 对象
JSONObject json = null;
try {
json = new JSONObject(jsonString);
} catch (JSONException e) {
throw new RuntimeException(e);
}
// 提取 username 的值
String username = null;
String password = null;
try {
username = json.getString("username");
password = json.getString("password");
} catch (JSONException e) {
throw new RuntimeException(e);
}
boolean success = "admin".equals(username) && "123".equals(password);
JSONObject jsonResponse = new JSONObject();
try {
jsonResponse.put("success", success);
} catch (JSONException e) {
throw new RuntimeException(e);
}
response.getWriter().write(jsonResponse.toString());