springmvc解决AJAX跨域
用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面由于安全方面的原因,客户端js使用xmlhttprequest只能用来向来源网站发送请求。
·
什么是AJAX 跨域访问
用户访问A网站时所产生的对B网站的跨域访问请求均提交到A网站的指定页面
由于安全方面的原因, 客户端js使用xmlhttprequest只能用来向来源网站发送请求
AJAX跨域解决方案
- JSONP
- CORS
- 使用代理服务器
封装工具类
package com.lihaozhe.ssm.util.response;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 上午10:17
*/
public enum ResultCode {
/**
* 操作成功 请求成功
*/
SUCCESS("200", "操作成功", "请求成功"),
/**
* 重定向 重定向
*/
LOCATION("302", "重定向", "重定向"),
/**
* 用户未认证
*/
UNAUTHORIZED("401", "用户未认证,禁止访问", "服务器拒绝了你的地址请求,账号或者密码错误"),
/**
* 用户未授权
*/
FORBIDDEN("403", "用户未授权,禁止访问", "服务器拒绝了你的地址请求,很有可能是您没权限访问"),
/**
* 账号不能为空 账号不能为空
*/
ACCOUNT_ISNULL("601", "账号不能为空", "账号不能为空"),
/**
* 密码不能为空 密码不能为空
*/
PASSWORD_ISNULL("602", "密码不能为空", "密码不能为空"),
/**
* 确认密码不能为空 确认密码不能为空
*/
REPASSWORD_ISNULL("603", "确认密码不能为空", "确认密码不能为空"),
/**
* 原始密码不能为空
*/
OPASSWORD_ISNULL("604", "原始密码不能为空", "原始密码不能为空"),
/**
* 新密码与原始密码一致
*/
PASSWORD_NOCHANGE("605", "新密码与原始密码一致,无需修改", "新密码与原始密码一致,无需修改"),
/**
* 新密码与确认密码不一致
*/
INCONSISTENT_PASSWORDS("606", "新密码与确认密码不一致", "新密码与确认密码不一致"),
/**
* 密码错误
*/
PASSWORD_ERROR("607", "密码错误", "密码错误"),
/**
* 该用被禁用
*/
ISDELETED("608", "数据已被删除", "数据已被删除"),
/**
* 操作失败 执行失败
*/
FAILED("10086", "执行失败", "执行失败"),
/**
* 参数错误 参数为空或格式不正确
*/
PARAM_ERROR("10001", "参数错误", "参数为空或格式不正确"),
/**
* 登录失败
*/
LOGIN_FAILED("10002", "登录失败", "登录失败"),
/**
* 账号锁定
*/
LOGIN_LOCKED("10003", "账号锁定", "账号锁定"),
/**
* appKey异常 appKey被冻结
*/
APPKEY_ERROR("10005", "appKey异常", "appKey被冻结"),
/**
* 验证码失效 redis中key失效
*/
TIMEOUT("10006", "验证码失效,请重新发送", "redis中key失效"),
/**
* 短信一发送,单位时间内,不会重新发送
*/
NO_TIMEOUT("10007", "短信已发送,请等待", "短信已发送,单位时间内,不会重新发送"),
/**
* 验证码错误
*/
CODE_ERROR("10008", "验证码错误,请重新输入", "客户端获取的验证码与redis中存储的验证码不一致"),
/**
* 短信一发送,单位时间内,不会重新发送
*/
NO_LOGIN("10009", "未登录状态", "未登录状态"),
/**
* 未知系统异常
*/
EXCEPTION("10010", "未知系统异常", "未知系统异常"),
/**
* 这是在主机名解析时通常出现的暂时错误,它意味着本地服务器没有从权威服务器上收到响应。
*/
UNKNOWN_HOST("10011", " 这是在主机名解析时通常出现的暂时错误,它意味着本地服务器没有从权威服务器上收到响应。", "这是在主机名解析时通常出现的暂时错误,它意味着本地服务器没有从权威服务器上收到响应。"),
/**
* 签名不一致
*/
INCONSISTENT_SIGNATURE("10012", "签名不一致", "签名不一致"),
/**
* 算法不匹配
*/
ALGORITHM_MISMATCH("10013", "算法不匹配", "算法不匹配"),
/**
* token过期失效
*/
TOKEN_EXPIRATION("10014", "token过期失效", "token过期失效"),
/**
* payload失效
*/
PALLOAD_INVALID("10015", "payload失效", "payload失效"),
/**
* 上传失败
*/
UPLOAD_FAILED("10016", "上传失败", "上传失败"),
/**
* appKey不存在 确认appKey是否正确
*/
APPKEY_NOTHINGNESS("10017", "appKey不存在", "确认appKey是否正确"),
/**
* 验证码不能为空
*/
CODE_ISNULL("10018", "验证码不能为空", "验证码不能为空"),
/**
* appkey和appSecret不匹配
*/
APPKEY_MISMATCHING("10030", "appkey和appSecret不匹配", "appkey和appSecret不匹配"),
/**
* 数据异常 接口调用异常
*/
DATA_ERROR("49999", "数据异常", "接口调用异常"),
/**
* 数据异常 接口调用异常
*/
DATA_EMPTY("50000", "未查询到数据", "未查询到数据"),
/**
* 手机号已经存在
*/
MOBILE_EXISTS("50001", "手机号已经存在", "手机号已经存在"),
/**
* 手机号不存在
*/
MOBILE_NOT_EXISTS("50002", "手机号不存在", "手机号不存在"),
/**
* 手机号格式错误
*/
MOBILE_INCORRECT("50003", "请输入正确手机号", "手机号格式不正确"),
/**
* 账号已经存在
*/
ACCOUNT_EXISTS("50011", "账号已经存在", "账号已经存在"),
/**
* 账号不存在
*/
ACCOUNT_NOT_EXISTS("50012", "账号不存在", "账号不存在");
/**
* 状态码
*/
private String code;
/**
* 返回消息
*/
private String msg;
/**
* 状态码
*/
private String desc;
ResultCode(String code, String msg, String desc) {
this.code = code;
this.msg = msg;
this.desc = desc;
}
public String getCode() {
return code;
}
public String getMsg() {
return msg;
}
public String getDesc() {
return desc;
}
}
package com.lihaozhe.ssm.util.response;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/13 上午10:11
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class ResponseResult<T> implements Serializable {
private static final long serialVersionUID = 5377037587784221010L;
/**
* 状态码
*/
private String code;
/**
* 返回消息
*/
private String msg;
/**
* 重定向地址
*/
private String location;
/**
* 令牌
*/
private String token;
private T data;
public ResponseResult(String code, String msg) {
this.code = code;
this.msg = msg;
}
/**
* 成功
*
* @return
*/
public static ResponseResult success() {
return new ResponseResult(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMsg());
}
/**
* 失败
*
* @return
*/
public static ResponseResult failed() {
return new ResponseResult(ResultCode.FAILED.getCode(), ResultCode.FAILED.getMsg());
}
/**
* 获取ResponseResult对象
*
* @return
*/
public static ResponseResult getInstance() {
return new ResponseResult();
}
}
package com.lihaozhe.ssm.util.json;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0
* @Description
* @createTime 2021/9/3 上午10:11
*/
public class BaseJacksonUtil {
// 定义jackson对象
private static final ObjectMapper MAPPER = new ObjectMapper();
/**
* 将对象转换成json字符串。
* <p>Title: pojoToJson</p>
* <p>Description: </p>
*
* @param data
* @return
*/
public static String objectToJson(Object data) {
try {
String string = MAPPER.writeValueAsString(data);
return string;
} catch (JsonProcessingException e) {
e.printStackTrace();
}
return null;
}
/**
* 将json结果集转化为对象
*
* @param jsonData json数据
* @param beanType 对象中的object类型
* @return
*/
public static <T> T jsonToPojo(String jsonData, Class<T> beanType) {
try {
T t = MAPPER.readValue(jsonData, beanType);
return t;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 将json数据转换成pojo对象list
* <p>Title: jsonToList</p>
* <p>Description: </p>
*
* @param jsonData
* @param beanType
* @return
*/
public static <T> List<T> jsonToList(String jsonData, Class<T> beanType) {
JavaType javaType = MAPPER.getTypeFactory().constructParametricType(List.class, beanType);
try {
List<T> list = MAPPER.readValue(jsonData, javaType);
return list;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.lihaozhe.ssm.util.servlet;
import com.lihaozhe.ssm.util.json.BaseJacksonUtil;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/25 上午9:34
*/
public class Servlet4Spring {
/**
* 向页面发送字符串
*
* @param response HttpServletResponse
* @param text 发送字符串
* @throws IOException
*/
public void printText(HttpServletResponse response, String text) throws IOException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(text);
writer.flush();
writer.close();
}
/**
* 向页面发送JSON格式字符串
*
* @param response HttpServletResponse
* @param object
* @throws IOException
*/
public void printJson(HttpServletResponse response, Object object) throws IOException {
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(BaseJacksonUtil.objectToJson(object));
writer.flush();
writer.close();
}
/**
* jsonp 向页面发送字符串
*
* @param request
* @param response
* @param text
* @throws IOException
*/
public void printText4Jsonp(HttpServletRequest request, HttpServletResponse response, String text) throws IOException {
String method = request.getParameter("callback");
String json = method + "(" + text + ")";
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(json);
writer.flush();
writer.close();
}
/**
* jsonp 向页面发送json格式字符串
*
* @param request
* @param response
* @param object
* @throws IOException
*/
public void printJson4Jsonp(HttpServletRequest request, HttpServletResponse response, Object object) throws IOException {
String method = request.getParameter("callback");
String json = method + "(" + BaseJacksonUtil.objectToJson(object) + ")";
response.setContentType("application/json;charset=utf-8");
PrintWriter writer = response.getWriter();
writer.println(json);
writer.flush();
writer.close();
}
}
SpringMVC 使用JSONP
package com.lihaozhe.spring.ssm.controller;
import com.lihaozhe.spring.ssm.bean.Emp;
import com.lihaozhe.spring.ssm.util.response.ResponseResult;
import com.lihaozhe.spring.ssm.util.response.ResultCode;
import com.lihaozhe.spring.ssm.util.servlet.Servlet4Spring;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/22 下午2:31
*/
//@Controller
@RestController
@RequestMapping("/person")
public class PersonController {
private final Servlet4Spring servlet4Spring;
public PersonController(Servlet4Spring servlet4Spring) {
this.servlet4Spring = servlet4Spring;
}
@GetMapping("/jsonp")
public void jsonp(Emp emp, HttpServletRequest request, HttpServletResponse response) throws IOException {
servlet4Spring.printJson4Jsonp(request,response,emp);
}
}
SpringMVC 使用CORS
注解方式
package com.lihaozhe.spring.ssm.controller;
import com.lihaozhe.spring.ssm.bean.Emp;
import com.lihaozhe.spring.ssm.util.response.ResponseResult;
import com.lihaozhe.spring.ssm.util.response.ResultCode;
import org.springframework.web.bind.annotation.*;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/22 下午2:31
*/
//@Controller
@RestController
@RequestMapping("/person")
@CrossOrigin(
value = "http://192.168.1.30:5500",
allowCredentials = "true",
allowedHeaders = "Origin, Accept, x-auth-token,Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, Code-Token, Access-Token")
public class PersonController {
@PostMapping("/login")
public Emp login(@RequestBody Emp emp) {
System.out.println(emp);
return emp;
}
}
xml方式
package com.lihaozhe.spring.ssm.controller;
import com.lihaozhe.spring.ssm.bean.Emp;
import com.lihaozhe.spring.ssm.util.response.ResponseResult;
import com.lihaozhe.spring.ssm.util.response.ResultCode;
import org.springframework.web.bind.annotation.*;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/22 下午2:31
*/
//@Controller
@RestController
@RequestMapping("/person")
public class PersonController {
@PostMapping("/login")
public Emp login(@RequestBody Emp emp) {
System.out.println(emp);
return emp;
}
}
<mvc:cors>
<mvc:mapping path="/**"
allowed-origins="http://192.168.1.30:5500/"
allow-credentials="true"
allowed-methods="POST, GET, PUT, PATCH, OPTIONS, DELETE"
allowed-headers="Origin, Accept, x-auth-token,Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, Code-Token, Access-Token"
max-age="3600"/>
</mvc:cors>
拦截器
package com.lihaozhe.ssm.intercepter;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/25 上午9:16
*/
public class IntercepterCors implements HandlerInterceptor {
public IntercepterCors() {
System.out.println(this.getClass().getSimpleName() + "出生了");
}
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
System.out.println("我是" + this.getClass().getSimpleName());
// ajax跨域
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Access-Control-Allow-Methods", "POST, GET, PUT, PATCH, OPTIONS, DELETE");
response.setHeader("Access-Control-Max-Age", "3600");
response.setHeader("Access-Control-Allow-Headers", "Origin, Accept, x-auth-token,Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, Code-Token, Access-Token");
// response.setHeader("Access-Control-Allow-Origin", "http://192.168.18.65:5500");
response.setHeader("Access-Control-Allow-Origin", request.getHeader("Origin"));
response.setHeader("Access-Control-Allow-Credentials", "true");
response.setHeader("XDomainRequestAllowed", "1");
String requestMethod = request.getMethod();
if ("OPTIONS".equalsIgnoreCase(requestMethod)) {
// 避免非正常请求发送到后端程序
return false;
}
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
<mvc:interceptors>
<mvc:interceptor>
<!-- 拦截哪些url -->
<mvc:mapping path="/**"/>
<!-- 不拦截哪些url -->
<mvc:exclude-mapping path="*.jsp"/>
<mvc:exclude-mapping path="/static/**"/>
<bean class="com.lihaozhe.ssm.intercepter.IntercepterCors"/>
</mvc:interceptor>
</mvc:interceptors>
Nginx反向代理
#user nobody;
worker_processes 1;
#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;
#pid logs/nginx.pid;
events {
worker_connections 1024;
}
http {
include mime.types;
default_type application/octet-stream;
#log_format main '$remote_addr - $remote_user [$time_local] "$request" '
# '$status $body_bytes_sent "$http_referer" '
# '"$http_user_agent" "$http_x_forwarded_for"';
#access_log logs/access.log main;
sendfile on;
#tcp_nopush on;
#keepalive_timeout 0;
keepalive_timeout 65;
#gzip on;
upstream tomcat-server{
# server 192.168.18.81:8080 weight=1 ;
server 192.168.18.81:8080;
server 192.168.18.82:8080;
server 192.168.18.83:8080;
server 192.168.18.84:8080;
# ip_hash;
}
server {
listen 80;
server_name localhost;
#charset koi8-r;
#access_log logs/host.access.log main;
location / {
# root html;
# index index.html index.htm demo.jsp;
# proxy_pass http://tomcat-server;
add_header 'Access-Control-Allow-Origin' *;
add_header 'Access-Control-Allow-Credentials' 'true';
add_header 'Access-Control-Allow-Methods' 'POST, GET, PUT, OPTIONS, DELETE';
add_header 'Access-Control-Allow-Headers' 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
add_header 'Access-Control-Allow-Headers' 'Origin, X-Requested-With, Content-Type, Accept';
proxy_pass http://192.168.18.17:6633;
proxy_redirect off;
proxy_headers_hash_max_size 1024;
proxy_headers_hash_bucket_size 512;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $http_x_forwarded_for;
client_max_body_size 20m;
}
#error_page 404 /404.html;
# redirect server error pages to the static page /50x.html
#
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
# proxy the PHP scripts to Apache listening on 127.0.0.1:80
#
#location ~ \.php$ {
# proxy_pass http://127.0.0.1;
#}
# pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
#
#location ~ \.php$ {
# root html;
# fastcgi_pass 127.0.0.1:9000;
# fastcgi_index index.php;
# fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
# include fastcgi_params;
#}
# deny access to .htaccess files, if Apache's document root
# concurs with nginx's one
#
#location ~ /\.ht {
# deny all;
#}
}
# another virtual host using mix of IP-, name-, and port-based configuration
#
#server {
# listen 8000;
# listen somename:8080;
# server_name somename alias another.alias;
# location / {
# root html;
# index index.html index.htm;
# }
#}
# HTTPS server
#
#server {
# listen 443 ssl;
# server_name localhost;
# ssl_certificate cert.pem;
# ssl_certificate_key cert.key;
# ssl_session_cache shared:SSL:1m;
# ssl_session_timeout 5m;
# ssl_ciphers HIGH:!aNULL:!MD5;
# ssl_prefer_server_ciphers on;
# location / {
# root html;
# index index.html index.htm;
# }
#}
}
更多推荐
已为社区贡献6条内容
所有评论(0)