淘淘商城項目_11
-
- 1、服務接口實作
-
- 1.1、檢查資料是否可用接口開發
-
- 1.1.1、功能分析
- 1.1.2、Dao
- 1.1.3、Service
- 1.1.4、釋出服務
- 1.1.5、引用服務
- 1.1.6、Controller
- 1.1.7、測試
- 1.2、使用者注冊接口開發
-
- 1.2.1、功能分析
- 1.2.2、Dao
- 1.2.3、Service
- 1.2.4、釋出服務
- 1.2.5、引用服務
- 1.2.6、Controller
- 1.2.7、測試
- 1.3、使用者登入接口開發
-
- 1.3.1、功能分析
- 1.3.2、Dao
- 1.3.3、Service
- 1.3.4、釋出服務
- 1.3.5、引用服務
- 1.3.6、Controller
- 1.3.7、測試
- 1.4、通過token查詢使用者資訊接口開發
-
- 1.4.1、功能分析
- 1.4.2、Dao
- 1.4.3、Service
- 1.4.4、釋出服務
- 1.4.5、引用服務
- 1.4.6、Controller
- 1.4.7、測試
- 1.5、安全退出接口開發
-
- 1.5.1、功能分析
- 1.5.2、Dao
- 1.5.3、Service
- 1.5.4、釋出服務
- 1.5.5、引用服務
- 1.5.6、Controller
- 1.5.7、測試
- 2、實作SSO系統的登入注冊功能
-
- 2.1、展示登入及注冊頁面及首頁超連結修改
- 2.2、注冊功能實作
- 2.3、登入功能實作
- 3、門戶首頁展示使用者名
-
- 3.1、首頁展示使用者名分析
- 3.2、jsonp原理
- 3.3、jsonp實作
-
- 3.3.1、用戶端:使用ajax自帶的callback函數
- 3.3.2、服務端:springmvc支援jsonp的兩種實作方法
課程計劃
- 1、SSO注冊功能實作
- 2、SSO登入功能實作
- 3、通過token獲得使用者資訊
- 4、ajax跨域請求解決方案–jsonp
1、服務接口實作
SSO系統就是解決分布式環境下登入問題的,本質上是解決分布式環境下session共享問題。
1.1、檢查資料是否可用接口開發
檢查資料是否可用作為注冊功能的輔助。

1.1.1、功能分析
請求的url:/user/check/{param}/{type}
參數:從url中取參數
1、String param(要校驗的資料)
2、Integer type(校驗的資料類型)
響應的資料:json資料。TaotaoResult,封裝的資料校驗的結果為true:表示成功,資料可用,false:失敗,資料不可用。
業務邏輯:
1、從tb_user表中查詢資料。
2、查詢條件根據傳遞過來的參數動态生成。
3、判斷查詢結果,如果查詢到資料就傳回false。
4、如果沒有查詢到資料就傳回true。
5、使用TaotaoResult包裝,并傳回。
1.1.2、Dao
從tb_user表查詢。屬于單表查詢,可以使用逆向工程生成的代碼。
1.1.3、Service
先在taotao-sso-interface中定義接口UserRegisterService,
再在taotao-sso-service中寫實作類。
參數:
1、要校驗的資料:String param
2、資料類型:Integer type(1、2、3分别代表username、phone、email)
傳回值:TaotaoResult
在taotao-sso-interface建立接口
/**
* 使用者注冊管理接口
* @author chenmingjun
* @date 2018年12月3日 上午9:47:29
* @version V1.0
*/
public interface UserRegisterService {
/**
* 檢查APP傳過來的資料是否可用
* @param param 要校驗的資料
* @param type 校驗的資料類型
* @return
*/
TaotaoResult checkData(String param, Integer type);
}
在taotao-sso-service建立實作類
@Autowired
private TbUserMapper tbUserMapper;
@Override
public TaotaoResult checkData(String param, Integer type) {
// 1、從tb_user表中查詢資料
TbUserExample example = new TbUserExample();
Criteria criteria = example.createCriteria();
// 2、查詢條件根據傳遞過來的參數動态生成
// 1、2、3分别代表username、phone、email
if (type == 1) {
criteria.andUsernameEqualTo(param);
} else if (type == 2) {
criteria.andPhoneEqualTo(param);
} else if (type == 3) {
criteria.andEmailEqualTo(param);
} else {
return TaotaoResult.build(400, "傳遞過來的是非法的參數");
}
// 執行查詢
List<TbUser> list = tbUserMapper.selectByExample(example);
// 3、判斷查詢結果,如果查詢到資料就傳回false
if (list == null || list.size() == 0) {
// 4、如果沒有查詢到資料就傳回true
return TaotaoResult.ok(true);
}
// 5、使用TaotaoResult包裝,并傳回
return TaotaoResult.ok(false);
}
1.1.4、釋出服務
先在taotao-sso-service工程中的pom.xml檔案中配置對taotao-sso-interface的依賴,因為服務層釋出服務要通過該接口,
再在taotao-sso-service工程中的applicationContext-service.xml檔案中釋出服務:
1.1.5、引用服務
需要在taotao-sso-web中實作。
先在taotao-sso-web工程中的pom.xml檔案中配置對taotao-sso-interface的依賴,表現層調用服務要通過該接口,
在taotao-sso-web工程中的springmvc.xml檔案中引用服務:
1.1.6、Controller
請求的url:/user/check/{param}/{type}
參數:從url中取參數
1、String param(要校驗的資料)
2、Integer type(校驗的資料類型)
請求的方法:get。
響應的資料:json資料。TaotaoResult,封裝的資料校驗的結果,true:成功;false:失敗。
/**
* 使用者處理Controller
* @author chenmingjun
* @date 2018年12月3日 上午10:31:38
* @version V1.0
*/
@Controller
public class UserController {
@Autowired
private UserRegisterService userRegisterService;
@RequestMapping(value="/user/check/{param}/{type}", method=RequestMethod.GET)
@ResponseBody
public TaotaoResult checkData(@PathVariable String param, @PathVariable Integer type) {
TaotaoResult result = userRegisterService.checkData(param, type);
return result;
}
}
1.1.7、測試
get請求好測試,直接在浏覽器中輸入URL即可。
通路位址:http://localhost:8088/user/check/zhangsan/1
浏覽器報404錯誤,原因是:我們web.xml中配置的是攔截以“.html”為字尾的請求。
我們修改通路位址:http://localhost:8088/user/check/zhangsan/1.html
此時浏覽器報406錯誤。原因如下圖:
而且如果我們在請求後面加上“.html”的話,等于我們修改了接口開發文檔,這是不行的。
正确的做法是要攔截不帶字尾的請求,我們使用“/”即攔截所有請求,如下圖所示:
下面我們詳解406錯誤的形成原因?
答:當我們浏覽器出現406錯誤時,90%的原因是因為沒有導入jackson-core-2.4.2.jar這個包。10%的原因是我們請求的URL字尾是“.html”。為什麼呢?
原因是:在springMVC中使用注解@ResponseBody,springMVC認為對于字尾是“.html”的URL請求,服務端傳回的應該也是一個html頁面。但是如果服務端傳回的是一個java對象的話,那麼浏覽器不能将一個java對象轉換成一個html對象,即就會報406錯誤。(
這是一個大坑!
)
1.2、使用者注冊接口開發
1.2.1、功能分析
請求的url:/user/register
參數:表單的資料:username、password、phone、email
傳回值:json資料。TaotaoResult。
接收參數:使用TbUser對象接收。
請求的方法:post
業務邏輯:
1、使用TbUser接收送出的請求。
2、補全TbUser其他屬性。
3、
密碼要進行MD5加密
。
4、把使用者資訊插入到資料庫中。
5、傳回TaotaoResult.ok()。
1.2.2、Dao
可以使用逆向工程生成的代碼。
1.2.3、Service
在taotao-sso-interface中定義接口UserRegisterService已經定義好了,我們直接添加方法即可。
再在taotao-sso-service中寫實作類,我們已經定義好了,直接實作方法即可。
參數:TbUser
傳回值:TaotaoResult
在taotao-sso-interface建立接口
/**
* 使用者注冊
* @param tbUser 使用者表
* @return
*/
TaotaoResult register(TbUser tbUser);
}
在taotao-sso-service建立實作類
@Override
public TaotaoResult register(TbUser tbUser) {
// 1、校驗使用者名和密碼不能為空
if (StringUtils.isEmpty(tbUser.getUsername())) {
return TaotaoResult.build(400, "注冊失敗,使用者名不能為空");
}
if (StringUtils.isEmpty(tbUser.getPassword())) {
return TaotaoResult.build(400, "注冊失敗,密碼不能為空");
}
// 2、校驗資料的可用性
// 2.1 、校驗username是否可用
TaotaoResult checkData = checkData(tbUser.getUsername(), 1);
if (!(boolean) checkData.getData()) { // 說明username不可用,傳回400
return TaotaoResult.build(400, "使用者名已被使用");
}
// 2.2、校驗phone是否可用
if (StringUtils.isNotBlank(tbUser.getPhone())) { // 說明phone不為空
if (!(boolean) checkData.getData()) { // 說明phone不可用,傳回400
return TaotaoResult.build(400, "手機号已被使用");
}
}
// 2.3、校驗email是否可用
if (StringUtils.isNotBlank(tbUser.getEmail())) { // 說明email不為空
if (!(boolean) checkData.getData()) { // 說明email不可用,傳回400
return TaotaoResult.build(400, "郵箱已被使用");
}
}
// 補全TbUser其他屬性
tbUser.setCreated(new Date());
tbUser.setUpdated(tbUser.getCreated());
// 密碼的MD5加密處理
String password = tbUser.getPassword();
String md5Password = DigestUtils.md5DigestAsHex(password.getBytes());
tbUser.setPassword(md5Password);
// 把使用者資訊插入到資料庫中
tbUserMapper.insertSelective(tbUser);
return TaotaoResult.ok();
}
1.2.4、釋出服務
在taotao-sso-service工程中applicationContext-service.xml檔案中釋出服務,上面“1.1.4”中已經釋出過了。不在贅圖!
1.2.5、引用服務
在taotao-sso-web工程中的springmvc.xml檔案中引用服務,上面“1.1.5”中已經引用過了。不在贅圖!
1.2.6、Controller
請求的url:/user/register
參數:表單的資料:username、password、phone、email
傳回值:json資料。TaotaoResult。
接收參數:使用TbUser對象接收。
請求的方法:post
@RequestMapping(value="/user/register", method=RequestMethod.POST)
@ResponseBody
public TaotaoResult register(TbUser tbUser) {
TaotaoResult result = userRegisterService.register(tbUser);
return result;
}
1.2.7、測試
post請求不好測試,需要我們建立表單,太麻煩了,我們可以使用一個工具。如下:
可以使用
restclient-ui-3.5-jar-with-dependencies.jar
測試接口。
點選編輯按鈕,填寫表單送出的content-type:application/x-www-form-urlencoded
點選插入參數按鈕,填寫參數後,點選生成。
點選送出按鈕,測試開始。
1.3、使用者登入接口開發
1.3.1、功能分析
請求的url:/user/login
請求的方法:POST
參數:username、password,表單送出的資料。可以使用方法的形參接收。
傳回值:json資料,使用TaotaoResult包含一個token。
業務邏輯:
登入的業務流程:
登入的處理流程:
1、登入頁面送出使用者名密碼。
2、登入成功後生成token。token相當于原來的jsessionid,字元串,可以使用uuid。
3、把使用者資訊儲存到redis。key就是token,value就是TbUser對象轉換成的json字元串。
4、使用String類型儲存session資訊。可以使用
“字首:token”
為key。
5、設定key的過期時間。模拟session的過期時間。一般半個小時。
6、把token寫入cookie中。
7、cookie需要跨域。例如:www.taotao.com\sso.taotao.com\order.taotao.com,可以使用工具類。
8、cookie的有效期。關閉浏覽器失效。
9、登入成功。
1.3.2、Dao
查詢tb_user表。單表查詢。可以使用逆向工程生成的代碼。
1.3.3、Service
參數:
1、使用者名:String username
2、密碼:String password
傳回值:TaotaoResult,包裝token。
業務邏輯:
1、判斷使用者名和密碼是否正确。
2、登入成功後生成token。token相當于原來的jsessionid,字元串,可以使用uuid。
3、把使用者資訊儲存到redis。key就是token,value就是TbUser對象轉換成的json串。
4、使用String類型儲存session資訊。可以使用“字首:token”為key。
5、設定key的過期時間。模拟session的過期時間。一般半個小時。
6、傳回TaotaoResult包裝token。
部分代碼:需要設定加載屬性檔案。
在taotao-sso-interface建立接口
/**
* 使用者登入管理接口
* @author chenmingjun
* @date 2018年12月3日 下午6:04:21
* @version V1.0
*/
public interface UserLoginService {
/**
* 根據使用者名和密碼進行登入,生成token作為key,user作為value
* @param username
* @param password
* @return
*/
TaotaoResult login(String username, String password);
}
在taotao-sso-service建立實作類
@Service
public class UserLoginServiceImpl implements UserLoginService {
@Autowired
private TbUserMapper tbUserMapper;
// 注入jedisClient對象
@Autowired
private JedisClient jedisClient;
@Value("${USER_SESSION}")
private String USER_SESSION;
@Value("${SESSION_EXPIRE}")
private Integer SESSION_EXPIRE;
@Override
public TaotaoResult login(String username, String password) {
// 1、判斷使用者名和密碼是否正确。
TbUserExample example = new TbUserExample();
Criteria criteria = example.createCriteria();
criteria.andUsernameEqualTo(username);
// 查詢使用者資訊,校驗使用者名
List<TbUser> list = tbUserMapper.selectByExample(example);
if (list == null || list.size() == 0) { // 說明沒有查詢到使用者資訊,即使用者名輸入錯誤
return TaotaoResult.build(400, "使用者名或密碼錯誤");
}
// 取出使用者資訊,校驗密碼
TbUser tbUser = list.get(0);
if (!DigestUtils.md5DigestAsHex(password.getBytes()).equals(tbUser.getPassword())) { // 說明密碼不正确
return TaotaoResult.build(400, "使用者名或密碼錯誤");
}
// 2、登入成功後生成token。token相當于原來的jsessionid,字元串,可以使用uuid。
String token = UUID.randomUUID().toString();
// 我們密碼就不要存到redis中了,是以要清空密碼
tbUser.setPassword(null);
// 3、把使用者資訊儲存到redis。key就是token,value就是TbUser對象轉換成的json串。
// 4、使用String類型儲存session資訊。可以使用“字首:token”為key。
jedisClient.set(USER_SESSION + ":" + token, JsonUtils.objectToJson(tbUser));
// 5、設定key的過期時間。模拟session的過期時間。一般半個小時。
jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
// 6、傳回TaotaoResult包裝token。
return TaotaoResult.ok(token);
}
}
1.3.4、釋出服務
在taotao-sso-service工程中applicationContext-service.xml檔案中釋出服務:
在taotao-sso-service工程中applicationContext-dao.xml檔案中加載配置檔案:
配置檔案内容如下:
1.3.5、引用服務
在taotao-sso-web工程中的springmvc.xml檔案中引用服務:
1.3.6、Controller
請求的url:/user/login
請求的方法:POST
參數:username、password,表單送出的資料。
因為隻有兩個參數,是以不用使用pojo來接收,可以使用方法的形參接收就可以。
從傳回結果中取出token,寫入cookie。需要使用HttpServletRequest、HttpServletResponse
傳回值:json資料,使用TaotaoResult包含一個token。
業務邏輯:
1、接收表單送出的兩個參數。
2、調用Service層的方法進行登入。
3、從傳回結果中取token,寫入cookie。注意:cookie要跨域。
cookie的二級域名跨域需要進行設定
:
1)setDomain(),設定一級域名:
.itcast.cn
.taotao.com
.taotao.com.cn
2)setPath(),設定為“/”
可以使用工具類。工具類放到taotao-common工程中。
需要加入servlet-api的依賴包:在common項目中的pom.xml中,加入依賴:
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<scope>provided</scope>
</dependency>
注意:
scope
的值是
provided
,表示
該jar包在運作時使用
、
編譯時使用
、
測試時用
,但是
打包的時候不用
,因為該jar包web容器tomcat會提供,如果打包的時候使用該jar包,會
出現沖突
。
4、響應資料。json資料。TaotaoResult,其中包含token。
@RequestMapping(value="/user/login", method=RequestMethod.POST)
@ResponseBody
public TaotaoResult login(String username, String password, HttpServletRequest request, HttpServletResponse response) {
// 1、接收表單送出的兩個參數。
// 2、調用Service層的方法進行登入。
TaotaoResult result = userLoginService.login(username, password);
// 3、從傳回結果中取出token,寫入cookie。注意:cookie要跨域。
if (result.getStatus() == 200) {
String token = result.getData().toString(); // 從傳回結果中取出token
CookieUtils.setCookie(request, response, COOKIE_TOKEN_KEY, token);
}
return result;
}
在taotao-sso-web工程中springmvc.xml檔案中加載配置檔案:
配置檔案内容如下:
1.3.7、測試
使用
restclient-ui-3.5-jar-with-dependencies.jar
測試接口,檢視Body;然後檢視redis伺服器中的key。
1.4、通過token查詢使用者資訊接口開發
1.4.1、功能分析
請求的url:/user/token/{token}
參數:String token(需要從url中取)
傳回值:json資料。使用TaotaoResult包裝Tbuser對象。
業務邏輯:
1、從url中取參數。
2、根據token查詢redis。
3、如果查詢不到資料,則傳回使用者已經過期。
4、如果查詢到資料,則說明使用者已經登入。
5、需要重置key的過期時間。
6、把json資料轉換成TbUser對象,然後使用TaotaoResult包裝并傳回。
1.4.2、Dao
使用JedisClient對象進行查詢。
1.4.3、Service
參數:String token
傳回值:TaotaoResult
在taotao-sso-interface建立接口
/**
* 根據token從redis中查詢使用者資訊
* @param token
* @return
*/
TaotaoResult getUserByToken(String token);
在taotao-sso-service建立實作類
@Override
public TaotaoResult getUserByToken(String token) {
// 2、根據token查詢redis。
String jsonString = jedisClient.get(USER_SESSION + ":" + token);
if (StringUtils.isBlank(jsonString)) {
// 3、如果查詢不到資料,則傳回使用者已經過期。
return TaotaoResult.build(400, "使用者登入狀态已過期,請重新登入");
}
// 4、如果查詢到資料,則說明使用者已經登入。
// 5、需要重置key(USER_SESSION)的過期時間。
jedisClient.expire(USER_SESSION + ":" + token, SESSION_EXPIRE);
// 6、把json資料轉換成TbUser對象,然後使用TaotaoResult包裝并傳回。
TbUser tbUser = JsonUtils.jsonToPojo(jsonString, TbUser.class);
return TaotaoResult.ok(tbUser);
// return TaotaoResult.ok(json);
}
注意:如果傳回的是:return TaotaoResult.ok(json);
那麼傳回的json串中會有轉義字元,如下:
{
"status": 200
"msg": "OK"
"data": "{\"id\":1,\"username\":\"zhangsan\",\"password\":null,\"phone\":\"15800807944\",\"email\":\"[email protected]\",\"created\":1414119176000,\"updated\":1414119179000}"
}
這跟我們接口開發文檔中的格式不一樣,接口開發文檔中的格式如下:
{
"status": 200
"msg": "OK"
"data": {"id":1,"username":"zhangzhijun","password":null,"phone":"15800807944","email":"[email protected]","created":1414119176000,"updated":1414119179000}
}
1.4.4、釋出服務
在taotao-sso-service工程中applicationContext-service.xml檔案中釋出服務,上面“1.3.4”中已經釋出過了。不在贅圖!
1.4.5、引用服務
在taotao-sso-web工程中的springmvc.xml檔案中引用服務,上面“1.3.5”中已經引用過了。不在贅圖!
1.4.6、Controller
請求的url:/user/token/{token}
參數:String token (需要從url中取)
傳回值:json資料。使用TaotaoResult包裝Tbuser對象。
@RequestMapping(value="/user/token/{token}", method=RequestMethod.GET)
@ResponseBody
public TaotaoResult getUserByToken(@PathVariable String token) {
TaotaoResult result = userLoginService.getUserByToken(token);
return result;
}
1.4.7、測試
get請求好測試,直接在浏覽器中輸入URL即可。
通路位址:http://localhost:8088/user/token/cd3c4925-c780-4e15-b8c2-ca9dc764fe47
1.5、安全退出接口開發
1.5.1、功能分析
需要根據token删除redis中對應的key。
從接口文檔可知
url:user/logout/{token}
參數:token
傳回值:由TaotaoResule封裝的資訊"ok"。
1.5.2、Dao
直接使用RedisClient通路redis。
1.5.3、Service
在taotao-sso-interface建立接口
/**
* 根據token從redis删除對應的key
* @param token
* @return
*/
TaotaoResult logout(String token);
在taotao-sso-service建立實作類
@Override
public TaotaoResult logout(String token) {
jedisClient.expire(USER_SESSION + ":" + token, 0);
return TaotaoResult.ok();
}
1.5.4、釋出服務
在taotao-sso-service工程中applicationContext-service.xml檔案中釋出服務,上面“1.3.4”中已經釋出過了。不在贅圖!
1.5.5、引用服務
在taotao-sso-web工程中的springmvc.xml檔案中引用服務,上面“1.3.5”中已經引用過了。不在贅圖!
1.5.6、Controller
url:user/logout/{token}
參數:token
@RequestMapping(value="/user/logout/{token}", method=RequestMethod.GET)
@ResponseBody
public TaotaoResult logout(@PathVariable String token) {
TaotaoResult result = userLoginService.logout(token);
return result;
}
1.5.7、測試
安裝taotao-sso,啟動taotao-sso、taotao-sso-web。
從redis中找一個存在的token:70ae13a6-87bb-4e3a-b713-35d7979c4bd8
使用RESETClirnt測試通路,删除token:70ae13a6-87bb-4e3a-b713-35d7979c4bd8 的使用者
提示删除成功!
2、實作SSO系統的登入注冊功能
2.1、展示登入及注冊頁面及首頁超連結修改
第一步:加入靜态檔案及JSP頁面
第二步:在taotao-sso-web的springmvc.xml檔案中配置資源映射标簽,即不攔截靜态資源。
第三步:點選門戶首頁登入按鈕,浏覽器URL為:
http://localhost:8084/page/login,報錯:
第四步:點選門戶首頁的免費注冊按鈕,浏覽器的URL為:
http://localhost:8084/page/register,報錯:
由此我們發現,其實登入注冊的URL非常類似:
http://localhost:8084/page/register
http://localhost:8084/page/login
是以通過
/page/{page}
的方式請求,通過
URL模闆映射
,使用
@PathVariable注解
即可接收請求,轉發jsp頁面,代碼如下:
使用rsetful,跳轉不同頁面
第五步:修改端口号為通路登入注冊的端口号為
8088
測試:通過。
2.2、注冊功能實作
/taotao-sso-web/src/main/webapp/WEB-INF/jsp/register.jsp分析:
送出之前檢查:
注冊,送出表單:
分析得出,此時的登入功能應該是可以使用了。
2.3、登入功能實作
/taotao-sso-web/src/main/webapp/WEB-INF/jsp/login.jsp分析:
文檔加載時,調用方法,一旦點選,則送出表單:
表單送出:
分析得出,登入功能也是可以使用的。
3、門戶首頁展示使用者名
3.1、首頁展示使用者名分析
1、在taotao-sso-web工程中,當使用者登入成功後,在cookie中有token資訊。
2、在taotao-portal-web工程中,從cookie中取出token,攜帶token發送格式為jsonp的請求,根據token從taotao-sso-web工程中查詢使用者資訊。
3、把從taotao-sso-web工程中查詢到的使用者名展示到首頁taotao-portal-web工程中。
方案一:在Controller中取cookie中的token資料,調用sso服務查詢使用者資訊。
缺點:由于淘淘商城首頁footer.jsp,在每個系統中都有,可以在每一個系統的footer.jsp中寫一個ajax發起請求調用目前系統的Controller,設定模型資料,然後展示資料。麻煩!
方案二:當頁面加載完成後使用js取cookie中token的資料,使用ajax請求查詢使用者資訊的JSON資料。隻需要在頁面實作一次即可。
乍一看方案一與方案二是一樣的,其實不是,方案一需要在每一個系統都編寫Controller,方案二隻需要在taotao-sso-web編寫一個Controller即可。而且方案一是立即可行的,但是方案二的服務接口在sso系統中。sso.taotao.com(localhost:8088),在首頁顯示使用者名稱,首頁的域名是www.taotao.com(localhost:8082),使用ajax請求跨域了。
什麼是跨域:
1、域名不同。
2、域名相同端口不同。
例如:
www.taotao.com --> 請求 www.taobao.com 也是跨域
www.taotao.com --> 請求 sso.taotao.com 也是跨域
www.taotao.com:8080 --> www.taotao.com:8088 也是跨域
localhost:8080 --> localhost:8088 也是跨域
www.taotao.com --> www.taotao.com 不是跨域
隻有域名和端口完全一樣才不是跨域。
js不可以跨域請求JSON資料
。
解決js的跨域問題可以使用jsonp。
jsonp
不是新技術
是跨域的解決方案
。使用js的特性繞過跨域請求,特性:
js可以跨域加載js檔案
。
3.2、jsonp原理
舉個非常常見的例子,我們在html頭部一般都會引入很多js,甚至我們直接引用線上的js,比如我們引用官方網站的jQuery路徑加載進來也是可以的。jQuery的官方域名與我們的工程所在的域名肯定是不一樣的,但是不影響使用,這就是我們所說的js可以跨域請求js檔案!
即:ajax無法跨域請求别的url,我們可以使用ajax跨域加載js檔案。
http://localhost:8088/user/token/4ffd07a2-1f92-4601-94ff-2ab763931018?callback=fun
8088做處理:查詢到JSON資料,拼接成fun({“id”:1});
8082浏覽器加載fun({“id”:1});
調用fun方法,裡面參數就是JSON資料。做相關的處理。
更加詳細的解釋:
參考連結:https://blog.csdn.net/pdsu161530247/article/details/82189866
3.3、jsonp實作
3.3.1、用戶端:使用ajax自帶的callback函數
使用jQuery。
在/taotao-portal-web/src/main/webapp/js/taotao.js中:
使用ajax的dataType : “jsonp”,将success : function當做回調函數。
用戶端是taotao-portal-web工程:
taotao.js代碼如下:
3.3.2、服務端:springmvc支援jsonp的兩種實作方法
ajax設定的callback函數,我們在後端就需要封裝一個callback(jsondata),讓前端将jsondata作為參數調用。
方法一:springmvc4.1之前的實作方法
服務端是taotao-sso-web工程:
方法二:springmvc4.1之後的實作方法
springmvc4.1以後,下面兩行代碼會自動幫我們封裝callback(jsondata)
服務端是taotao-sso-web工程:
我的GitHub位址:https://github.com/heizemingjun
我的部落格園位址:https://www.cnblogs.com/chenmingjun
我的螞蟻筆記部落格位址:https://blog.leanote.com/chenmingjun
Copyright ©2018~2019 黑澤君
【轉載文章務必保留出處和署名,謝謝!】