zoukankan      html  css  js  c++  java
  • Ajax跨域访问解决办法

    方法1. jsonp实现ajax跨域访问示例

    jsp代码:

    <body>
        <input type="button" onclick="testJsonp();" value="TestJsonP">
    </body>

    js代码:

    function testJsonp(){
        $.ajax({
            type : 'GET',
            dataType : 'jsonp', // 数据类型配置成jsonp
            jsonp : "callback", //配置jsonp随机码标签,在服务器代码部分需要用到他来拼接一个json的js对象
            url : 'http://127.0.0.1:8001/test', //服务路径
            async : false,
            data: {
                "type":'0',
            },
            success : function (response) {
                if(response.code == 200){
                    alert('返回成功!');
                }else{
                    alert('服务器异常!');
                }
            },
            error : function (){
                alert('服务器异常!');
            }
        });
    }

    java代码:

        @RequestMapping(value = "/test", method = RequestMethod.GET)
        public @ResponseBody String testJsonp(@RequestParam(value = "type", defaultValue = "") String type, String callback) {
            RequestResult data = new RequestResult(); // 配置需要返回的结果
            data.setCode(200);
            data.setMessage("success");
            // 接收参数callback名称需要与js中配置的jsonp标签名一致
            String result = callback+"("+JSONObject.fromObject(data).toString()+")";//拼接可执行的js
            return result;
        }

    几个注意点:

    1. jsonp只支持GET方式的请求,无论ajax中的type配置成何种方式,都会在默认以GET方式发送请求。无法满足restful方式的请求。

    2. ajax中的jsonp的标签名要与服务端的接收标签参数一致。本例中都设置为'callback'.

    3. 若想传递一个json格式的js对象到服务器,可以使用JSON.stringify()方法将js对象转化为json字符串,赋值到某个变量。在服务器端获取这个变量的值通过json工具,将该字符串转化为java对象。

    方法2. 在服务器端放开访问权限,使允许接收ajax访问

    前端代码不需修改。

    java代码, 在BaseController中加入:   

        // protected HttpServletRequest request;
    protected
    HttpServletResponse response; // protected HttpSession session; @ModelAttribute public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) { // this.request = request; this.response = response; // this.session = request.getSession(); response.setHeader("Access-Control-Allow-Origin", "*"); } @RequestMapping(value = "/test", method = RequestMethod.GET) public @ResponseBody RequestResult test() { RequestResult result = new RequestResult(); result.setCode(200); result.setMessage("success");

    return result; }

    说明:ModelAttribute的作用
    1)放置在方法的形参上:表示引用Model中的数据
    2)放置在方法上面:表示请求该类的每个Action前都会首先执行它,也可以将一些准备数据的操作放置在该方法里面。

    这种方式只允许GET方式的请求,无法满足restful格式的请求。

    方法3.终极解决办法(方法2的升级版)

    前端代码不需修改。

    在服务器端写一个filter,在doFilter方法中全面放开访问权限,并将此filter配置到web.xml中,或直接使用注解,划入spring管理。此方法完全支持restful的ajax跨域请求。

    下面给一下spring mvc框架下的一个解决示例(亲测可用):

    import java.io.IOException;
    import javax.servlet.Filter;
    import javax.servlet.FilterChain;
    import javax.servlet.FilterConfig;
    import javax.servlet.ServletException;
    import javax.servlet.ServletRequest;
    import javax.servlet.ServletResponse;
    import javax.servlet.http.HttpServletResponse;
    import org.springframework.stereotype.Component;
    
    @Component("myFilter")
    public class MyFilter implements Filter {
    
        public void destroy() {
            // System.out.println("过滤器销毁");
        }
    
        public void doFilter(ServletRequest request, ServletResponse response1, FilterChain chain) throws IOException,
                ServletException {
            // System.out.println("执行过滤操作");
    
            HttpServletResponse response = (HttpServletResponse) response1;
    
            response.setHeader("Access-Control-Allow-Origin", "*");
    
            response.setHeader("Access-Control-Allow-Headers",
                    "User-Agent,Origin,Cache-Control,Content-type,Date,Server,withCredentials,AccessToken");
    
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            response.setHeader("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
    
            response.setHeader("Access-Control-Max-Age", "1209600");
    
            response.setHeader("Access-Control-Expose-Headers", "accesstoken");
    
            response.setHeader("Access-Control-Request-Headers", "accesstoken");
    
            response.setHeader("Expires", "-1");
    
            response.setHeader("Cache-Control", "no-cache");
    
            response.setHeader("pragma", "no-cache");
    
            chain.doFilter(request, response);
        }
    
        public void init(FilterConfig arg0) throws ServletException {
            // System.out.println("过滤器初始化");
        }
    
    }

    参考文章:

    Ajax跨域(jsonp) 调用JAVA后台 (http://www.cnblogs.com/holdon521/p/5282354.html)

    springMVC获取request和response (http://blog.sina.com.cn/s/blog_7085382f0102v9jg.html)

    REST跨域访问解决CorsFilter (http://blog.csdn.net/u013628152/article/details/49490213)

    Spring Boot 过滤器、监听器 (http://blog.csdn.net/catoop/article/details/50501688)

  • 相关阅读:
    动态规划最大利润的问题
    【转】mysql基础汇总
    mac使用frida
    Mac 下python3 [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed 解决方法
    mac使用jadx逆向app
    python桶排序代码
    requests_html使用asyncio
    async for的使用
    [转载]微信企业号:企业客户的移动应用入口
    微信服务号、订阅号、企业号差别
  • 原文地址:https://www.cnblogs.com/zj0208/p/6022218.html
Copyright © 2011-2022 走看看