解決跨域問題
1 什么是跨域
跨域:是指一個域下的文檔或腳本試圖去請求另一個域下的資源,這里跨域是廣義的。通常所說的跨域是狹義的,是由瀏覽器同源策略限制的一類請求場景。從一個域名的網頁去請求另一個域名的資源時,域名、端口、協議任一不同,都是跨域。
**域名:記憶網絡電腦ip很難記,就給它取了一個名字來記憶,這個名字就要域名,域名最終要被轉換為ip. 如:www.baidu.com 轉化為ip為:http://14.215.177.39/
2 跨域原因
域名不同 www.jd.com 與 www.taobao.com
域名相同,端口不同 www.jd.com:8080 與 www.jd.com:8081
二級域名不同 item.jd.com 與 miaosha.jd.com
www.baidu.wenku.com www.baid.tieba.com
如果域名和端口都相同,但是請求路徑不同,不屬於跨域,如:
www.jd.com/item
www.jd.com/goods
只要域名(ip)和端口號有一樣不同,那么都是跨域
一個系統訪問另一個系統才會存在跨域,同系統訪問不存在跨.
3 跨域問題
跨域不一定會有跨域問題。
因為跨域問題是瀏覽器對於ajax請求的一種安全限制:一個頁面發起的ajax請求,只能是於當前頁同域名的路徑,這能有效的阻止跨站攻擊。
因此:跨域問題 是針對ajax的一種限制。
**本質原因是:瀏覽器的同源策略:只允許 相同協議 相同域名 相同的端口**
但是這卻給我們的開發帶來了不變,而且在實際生成環境中,肯定會有很多台服務器之間交互,地址和端口都可能不同,怎么辦?
4 跨域問題的解決方案
(1)jsonp--很早的
動態的構造的 標簽 <script >去訪問資源
缺陷:
get請求/服務支持
(2)通過nginx (部署) -- 解決跨域問題 -- 反向代理機制
類似 中間商 ,把訪問后台的請求 轉換訪問自己, 讓那個nginx去訪問后台,把結果那會,在轉給前台
缺點:
部署服務,做配置
(3) CORS機制: 跨域資源共享"(Cross-origin resource sharing) "
解決 跨域問題 (瀏覽器有同源策略,(相同域名,相同的端口,相同協議),如果不是同源,存在跨域問題)
發送請求: 普通請求 發送一次,后台服務需要運行訪問 ..
特殊請求 發送二次, 第一次是預檢請求, 服務器也要運行預檢, 前台發現預檢通過,在發送真實請求 , 真實請求也需要服務器允許
解決:都需要服務允許
**注解方式: 版本 spring版本 4.2 以上才支持注解**
nginx 反向代理圖
5 使用@CrossOrigin注解解決跨域問題
前提:spring版本至少4.2以上 (我使用的4.3.3沒問題)
直接在控制層類上加一個注解@CrossOrigin就可以了
package cn.itsource.crm.web.controller;
import cn.itsource.crm.common.domain.Department;
import cn.itsource.crm.common.query.DepartmentQuery;
import cn.itsource.crm.service.IDepartmentService;
import cn.itsource.util.AjaxResult;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@Controller
@RequestMapping("/department")
@CrossOrigin
public class DepartmentController {
@Autowired
private IDepartmentService departmentService;
/**
* 查詢所有
* @return
*/
@RequestMapping(value = "/list",method = RequestMethod.PATCH)
@ResponseBody
public List<Department> findAll(){
List<Department> departmentList = departmentService.findAll();
return departmentList;
}
/**
* 新增
*/
@RequestMapping(method = RequestMethod.PUT)
@ResponseBody
public AjaxResult add(@RequestBody Department department){
System.out.println("新增:"+department);
departmentService.add(department);
return new AjaxResult();
}
/**
* 修改
*/
@RequestMapping(method = RequestMethod.POST)
@ResponseBody
public AjaxResult update(@RequestBody Department department) {
// System.out.println("修改:" + department);
departmentService.update(department);
return new AjaxResult();
}
/**
* 刪除
*/
@RequestMapping(value = "/{id}",method = RequestMethod.DELETE)
@ResponseBody
public AjaxResult delete(@PathVariable Long id) {
// System.out.println("刪除:" + id);
departmentService.delete(id);
return new AjaxResult();
}
/**
* 查詢一條
* @return
*/
@RequestMapping(value = "/{id}",method = RequestMethod.GET)
@ResponseBody
public AjaxResult findOne(@PathVariable Long id) {
// System.out.println("查詢id:" + id);
departmentService.findOne(id);
return new AjaxResult();
}
/**
* 根據名字查詢
*/
@RequestMapping(value = "/queryByName",method = RequestMethod.PATCH)
@ResponseBody
public List<Department> queryByName(@RequestBody DepartmentQuery dep){
// System.out.println("接受參數為:"+dep);
List<Department> departmentList = departmentService.queryByName(dep);
return departmentList;
}
}