【js】Jsonp解决js跨域问题

您所在的位置:网站首页 猴哥新传 【js】Jsonp解决js跨域问题

【js】Jsonp解决js跨域问题

2024-01-05 07:51| 来源: 网络整理| 查看: 265

一、前言

      前一段使用的项目中,采用的框架是Dubbo+ZK+Spring+Springmvc。这个架构前端和服务分离,也就是说,前端和服务的域名是不一样的,所以访问就涉及到了“跨域”。下面小编就向大家介绍一下跨域,以及如何处理这种问题。

二、什么是“Js跨域”

      做过前端的都知道js为了安全,有一个限制,不允许跨域访问。

      那跨域是什么呢?

访问的两个域名不同url相同,但是端口不同ip相同,端口不同

      举个例子:

      看下面的这张图,由两部分组成,前端系统和服务系统。当前端使用异步调用服务的时候,使用ajax是不可以直接调用的。

这里写图片描述

三、使用jsonp解决跨域问题

1、在js中不能跨域请求数据,js可以跨域请求js片段。

我们都使用js,使用之前需要对js引用。 比如我们引用jquery,我们可以使用 Google 的 CDN。这样就是可以请求js片段。

2、可以把数据包装成js片段。可以把数据使用js方法来包装,形成一条方法的调用语句。

3、可以使用ajax请求js片段,当js片段到达浏览器会被立即执行。

4、在浏览器端,先创建好回调方法,在回调方法中通过参数可以获得请求的数据。

这里写图片描述

四、实战demo

      下面小编通过写一个和京东相似的显示商品类目的方法来展示一下:

这里写图片描述

      这个功能是鼠标移动到列表的位置,就会显示二级菜单信息。       前台接收的数据是json,结构如下:

{ "data": [ { "u": "/products/1.html", "n": "图书、音像、电子书刊", "i": [ { "u": "/products/2.html", "n": "电子书刊", "i": [ "/products/3.html|电子书", "/products/4.html|网络原创", "/products/5.html|数字杂志", "/products/6.html|多媒体图书" ] } ] } ] }

      在前端js中,调用数据如下:

var category = {OBJ: $("#_JD_ALLSORT"), URL_Serv: "http://localhost:8081/rest/item/cat/list?callback=category.getDataService", //URL_Serv: "http://localhost:8081/category.json", FN_GetData: function() { //使用jsonp来实现跨域请求 $.getJSONP(this.URL_Serv, category.getDataService); //直接使用ajax请求json数据 /*$.getJSON(this.URL_Serv, function(json){ category.getDataService(json); });*/ },getDataService: function(a) { var b = [], c = this; $.each(a.data, function(a) { this.index = a, "l" == this.t && (this.i = c.FN_RefactorJSON(this.i, 7)), b.push(c.renderItem(this, a)) }); b.push('\u5168\u90e8\u5546\u54c1\u5206\u7c7b'), this.OBJ.attr("load", "1").html(b.join("")), $.bigiframe(this.OBJ), this.FN_GetBrands(); var d = this, e = this.OBJ.outerWidth(), f = this.OBJ.outerHeight(); $("#_JD_ALLSORT").dropdown({delay: 0,onmouseleave: function() { $("#_JD_ALLSORT .item").removeClass("hover") }}, function(a) { var b, c, g = document.documentElement.scrollTop + document.body.scrollTop, h = $("#nav-2013").offset().top + 39; h >= g ? (c = a.hasClass("fore13") ? 3 : 3, g = c) : (b = a.offset().top, g = g > b - 5 ? b - h - 10 : Math.max(3, g - h)); var i = a.find(".i-mc"); if (i.css({top: g + "px"}), d.OBJ.find("iframe")) { var j = i.outerWidth() + e, k = i.outerHeight() > f ? i.outerHeight() : f; d.OBJ.find("iframe").css({width: j,height: k,top: g}) } }) } }();

      在上面的代码上可以看出,我们通过AJAX请求的路径为“http://localhost:8081/rest/item/cat/list?callback=category.getDataService”,而本前端的域名是“http://localhost:8082”,这个就涉及到了js跨域问题,使用已经注释的$.getJSON访问是获取不到json数据的。因为,我们获取到json后,要执行getDataService方法,把返回的json解析拼成html页面。

      使用 $.getJSONP是可以访问封装好的js片段。既然咱们需要返回的是json,返回后要传给getDataService(json),就可以直接返回类似为getDataService(json)的js片段:

category.getDataService({ "data": [ { "u": "/products/1.html", "n": "图书、音像、电子书刊", "i": [ { "u": "/products/2.html", "n": "电子书刊", "i": [ "/products/3.html|电子书", "/products/4.html|网络原创", "/products/5.html|数字杂志", "/products/6.html|多媒体图书" ] } ] } ] });

      服务端获取json服务:

      ItemCatController:

package com.taotao.rest.controller; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.MediaType; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import com.taotao.common.util.JsonUtils; import com.taotao.rest.pojo.ItemCatResult; import com.taotao.rest.service.ItemCatService; @Controller @RequestMapping("/item/cat") public class ItemCatController { @Autowired private ItemCatService itemCatService; @RequestMapping(value="/list",produces=MediaType.APPLICATION_JSON_VALUE+";charset=utf-8") @ResponseBody public String getItemCatList(String callback){ ItemCatResult result = itemCatService.GetItemCatList(); if (StringUtils.isBlank(callback)) { //需要把result转换成字符串 String json = JsonUtils.objectToJson(result); return json; } //如果字符串不为空,需要指出jsonp调用 //需要把result转换成字符串 String json = JsonUtils.objectToJson(result); return callback+"("+json+")"; } }

      代码解析:

      在这个代码中,接收$.getJSONP的url传来的参数,http://localhost:8081/rest/item/cat/list?callback=category.getDataService ,然后获取json数据,如果有数据的话就返回callback+”(“+json+”)” ,是一个js片段,当这个片段返回到前端的浏览器中,会自动执行这个js片段,这个js片段正好是一个函数,执行后就获得了html页面。

五、小结

      解决js的跨域问题当然不只有这一种方法,而且这个也不是新的知识,不过也是可以解决问题的一种思路吧。希望以后可以更多的理解这个功能。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3