什么是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;
    #    }
    #}

}

Logo

长江两岸老火锅,共聚山城开发者!We Want You!

更多推荐