ajax 跨域请求

痞子三分冷 提交于 2020-01-01 01:20:46

一、使用ajax进行跨域请求是会出现错误:

Access to XMLHttpRequest at 'http://www.smarthui.top/memo/major.json' from origin 'http://localhost:8080' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.

二、解决方案:

(1) 在ajax中

dataType: "jsonp",//预期服务器返回的数据类型

datatype设置为jsonp。

JSON和JSONP虽然只有一个字母的差别,但其实他们根本不是一回事儿:JSON是一种数据交换格式,而JSONP是一种依靠开发人员的聪明才智创造出的一种非官方跨域数据交互协议。我们拿最近比较火的谍战片来打个比方,JSON是地下党们用来书写和交换情报的“暗号”,而JSONP则是把用暗号书写的情报传递给自己同志时使用的接头方式。

一个是描述信息的格式,一个是信息传递双方约定的方式。

为了便于客户端使用数据,逐渐形成了一种非正式传输协议,人们把它称作JSONP,该协议的一个要点就是允许用户传递一个callback参数给服务端,然后服务端返回数据时会将这个callback参数作为函数名来包裹住JSON数据,这样客户端就可以随意定制自己的函数来自动处理返回数据了。callback是什么意思呢,稍等下面有例子。

(2) 这时候虽然返回状态为200,但是会跑到ajax的error中,需要进行进一步设置。

在ajax中添加

jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
jsonpCallback:"successCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名

其中successCallback是返回数据的设置函数名

(3) 这时候也需要修改服务端传输的数据格式,不再是单纯的json格式,而是要加上自定义的jsonp回调函数名称,如下所示:

successCallback({
  "1":"215",
  "2":"216",
  "3":"217",
})

另外,和上面类似,另一种动态添加jsonpCallback函数名的方法:

        //获得callback方法名字
        String callbackFuncation = request.getParameter("callback");
        String msg = "{"1":"215","2":"216", "3":"217",";
        //callback方法名包裹真正信息
        return callbackFuncation+"("+msg+")";

(4)此时就可以在success中接收到json信息了。

success: function (result) {
    console.log(result);//打印服务端返回的数据(调试用)
    alert(result["1"])
},

三、完整的前端代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>HttpJson</title>
    <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
</head>
<script>
    $(document).ready(function () {
        $("#button").click(function () {

            $.ajax({

                type: "POST",//方法类型
                contentType: 'application/json; charset=utf-8',
                jsonp: "callback",//传递给请求处理程序或页面的,用以获得jsonp回调函数名的参数名(默认为:callback)
                jsonpCallback:"successCallback",//自定义的jsonp回调函数名称,默认为jQuery自动生成的随机函数名
                dataType: "jsonp",//预期服务器返回的数据类型
                url: "http://www.smarthui.top/memo/major.json",//url
                //data: dataStr,
                success: function (result) {
                    console.log(result);//打印服务端返回的数据(调试用)
                    alert(result["1"])
                },
                error: function (error) {
                    console.log(error);
                    alert(error.status + ':未知错误');
                }
            });

        });
    });
</script>
<body>
<button id="button">请求</button>
</body>
</html>

最后分享一个博客,很全很强:https://www.cnblogs.com/dowinning/archive/2012/04/19/json-jsonp-jquery.html

-------------------------------------------------------------------------------------------------------------------------------------------------

另外两种解决方案

1.      在后端设置响应头

/**设置响应头允许ajax跨域访问**/

response.setHeader("Access-Control-Allow-Origin","*");

2.      另外,对于spring boot项目,跨域请求时,加入一个Bean

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/*").allowedOrigins("http://localhost:8080");
        }
    };
}

这样就可以允许http://localhost:8080请求了。

或者在单个方法前加入 @CrossOrigin(origins = "http://localhost:9000")

表明该方法允许来自http://localhost:9000访问,也就是前端可以是localhost:9000。

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!