日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CORS 实战 专题

發布時間:2023/12/31 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CORS 实战 专题 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

本文會代碼層面對CORS問題進行剖析

CORS相關相關概念可參考http://www.cnblogs.com/softidea/p/5496719.html

?

ERROR info:

XMLHttpRequest cannot load http://localhost:8080/jsonp/scene1/user/1. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.

?

?

JSONP(Javascript Object Notation With Padding)需要客戶端和服務器支持

JSONP解釋
在解釋JSONP之前,我們需要了解下”同源策略“這個概念,這對理解跨域有幫助。
基于安全的原因,瀏覽器是存在同源策略機制的,同源策略阻止從一個源加載的文檔或腳本獲取或設置另一個源加載額文檔的屬性。有點繞,說的簡單點就是瀏覽器限制腳本只能和同協議、同域名、同端口的腳本進行交互。

什么是jsonp格式呢?
API原文:
如果獲取的數據文件存放在遠程服務器上(域名不同,也就是跨域獲取數據),則需要使用jsonp類型。
使用這種類型的話,會創建一個查詢字符串參數 callback=? ,這個參數會加在請求的URL后面。
服務器端應當在JSON數據前加上回調函數名,以便完成一個有效的JSONP請求。

意思就是遠程服務端需要對返回的數據做下處理,根據客戶端提交的callback的參數,返回一個callback(json)的數據,而客戶端將會用script的方式處理返回數據,來對json數據做處理。JQuery.getJSON也同樣支持jsonp的數據方式調用。


JSONP就是為了解決這一問題的,JSONP是英文JSON with Padding的縮寫,是一個非官方的協議。他允許服務端生成script tags返回值客戶端,通過JavaScript callback的形式來實現站點訪問。JSONP是一種script tag的注入,將server返回的response添加到頁面是實現特定功能。
簡而言之,JSONP本身不是復雜的東西,就是通過scirpt標簽對javascript文檔的動態解析繞過了瀏覽器的同源策略。
JSONP原理及實現
接下來,來實際模擬一個跨域請求的解決方案。后端為spring MVC架構的,前端則通過Ajax進行跨域訪問。
1、首先客戶端需要注冊一個callback(服務端通過該callback(jsonp)可以得到js函數名(jsonpCallback)),然后以JavaScript語
法的方式,生成一個function
2、接下來,將JSON數據直接以入參的方式,放置到function中,這樣就生成了一段js語法文檔,返回給客戶端。
3、最后客戶端瀏覽器動態的解析script標簽,并執行返回的JavaScript語法文檔片段,此時數據作為參數傳入到了預先定義好的
回調函數里(動態執行回調函數)。
這種動態解析js文檔和eval函數是類似的。

?

客戶端的支持:

This is how I'm using JSONP with Spring MVC, just modify it according to your needs:
on Server Side:
下例中服務器端處理參數名為“callback"的客戶端數據,此數據在客戶端的JS代碼必須存在,可以指定參數值,也不可以不指定,如果不指定,會由瀏覽器自動生成
類似下面這種格式:

http://localhost:8080/jsonp/scene1/user/1?callback=jQuery3210430263573155826_1502264239363&time=1502265440209&_=1502264239364



@RequestMapping(value="/notes/callback.json", method=RequestMethod.GET) public void jsonpCallback(@RequestParam("callback") String callback, HttpServletResponse response) {response.setContentType("text/javascript; charset=UTF-8");PrintWriter out = response.getWriter();out.print(callback + "(" + jsonDataString + ")"); }

On client side:

<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script> <script type="text/javascript">function yourfunction() {jQuery.getJSON("http://localhost:8080/notes/callback.json?callback=?", function(data) {alert(data.someParam);}); }</script>

?

指定callback參數對應的值:

$.ajax({url: "http://tonghuashuo.github.io/test/jsonp.txt",dataType: 'jsonp',jsonp: "callback",jsonpCallback: "dosomething" }) .done(function(res) {console.log("success");console.log(res); }) .fail(function(res) {console.log("error");console.log(res); });

后端關鍵代碼(以PHP為例)

$result = "{'data':'JSONP Works'}"; // 這里省略了數據庫查詢等操作,直接給出返回值 $callback = $_GET['callback']; // 最好加上判空和默認值,以防拿不到參數 echo $callback."(".$result.")";// 返回的結果 // dosomething({"data":"JSONP Works"});

將上述代碼放到你本地localhost中,嘗試運行一下,順利的話應該會在瀏覽器的控制臺中得到以下的內容:

> success > Object {data: "JSONP Works"}

實際發送出來的完整請求長這樣:http://tonghuashuo.github.io/test/jsonp.txt?callback=dosomething&_=1471419449018。,后面的隨機字符串是jQuery加上的。

區別于常規的 AJAX 請求,這里真正需要關心的參數有以下 3 個

  • dataType: 'jsonp',用于表示這是一個 JSONP 請求。
  • jsonp: 'callback',用于告知服務器根據這個參數獲取回調函數的名稱,通常約定就叫 callback。
  • jsonpCallback: 'dosomething',指定我們自己的回調函數名稱,也是前面callback參數的值。遠程服務接受callback參數的值就不再是自動生成的回調名

其中jsonpCallback參數是可以省略的,jQuery 會自動生成一個隨機字符串作為函數名,推薦這么做,以減少不必要的命名工作,同時排除潛在的安全隱患。這里由于Github Page沒有后臺服務,我們只能指定一個名字。注意:省略jsonpCallback的同時,jsonp參數必須指明,不能為false。

jQuery 還支持將jsonp設置為false以避免callback參數出現在請求 URL 中,但這需要前后端配合,前端必須要指定jsonpCallback的值為一個函數名,后端由于無法從請求中獲取回調函數的名稱,因此也必須固定使用同名的字符串進行拼接。



Spring 4 MVC + JSONP Example with REST, @ResponseBody and ResponseEntity
客戶端代碼示例:

$("#but1").click(function(){ $.ajax({ url:'http://127.0.0.1:8080/DevInfoWeb/get', type: "get", async: false, dataType: "jsonp", jsonp: "callbackparam", //服務端用于接收callback調用的function名的參數 jsonpCallback: "success_jsonpCallback", //callback的function名稱,服務端會把名稱和data一起傳遞回來 success: function(json) { alert(json); }, error: function(){alert('Error');} }); });

<script language="JavaScript"> $(document).ready(function() {$.ajax({url:'http://localhost:8080/test/getPopularity',dataType:'jsonp',success:function(data){console.log("返回Json:")console.log(data)}}); }); </script>

http://localhost:8080/test/getPopularity?callback=jsonp

?

?

In this page we will provide Spring 4 MVC and JSONP example with REST, @ResponseBody and ResponseEntity. JSONP is JSON with padding. It supports JavaScript code running in web browser to request data from a server in different domain which is normally prohibited because of same-origin policy. According to this policy a web browser can allow the script code of one web browser to access data from another web browser within the same domain. Same-origin policy is because of web application security model. But this policy is not forced to <script> tag by web browser. From here the role of JSONP comes into picture. JSONP allows to access data from different domain using <script> tag by web browser. If we have a URL as
http://localhost:8080/concretepage-1/book1?callback=myfunction
and if it throws the JSONP response as

myfunction({"bookName":"Godan","writer":"Premchand"});

then in another domain, we can use it as?

<script src=" http://localhost:8080/concretepage-1/book1?callback=myfunction " type="application/javascript"> </script>

In our client code to access JSONP, there should already be a function named myfunction() defined in script code.
To throw the JSONP response using spring, it provides AbstractJsonpResponseBodyAdvice class which is implemented by a class annotated with @ControllerAdvice.

Spring 4 Support for JSONP with AbstractJsonpResponseBodyAdvice
Find the our class which will support JSONP response.
JsonpAdvice.java

@ControllerAdvice public class JsonpAdvice extends AbstractJsonpResponseBodyAdvice {public JsonpAdvice() {super("callback");} }

In the constructor, we need to call super method passing a key. This key will be used in query string of URL while requesting JSONP data. The above method facilitates REST web service to respond JSONP data and also controller method which respond using @ResponseBody and ResponseEntity.
JSONP with Spring REST
Find the bean being used in the example to generate JSON.
Book.java

public class Book {private String bookName;private String writer;public String getBookName() {return bookName;}public void setBookName(String bookName) {this.bookName = bookName;}public String getWriter() {return writer;}public void setWriter(String writer) {this.writer = writer;} }

We are creating a web service which will respond JSONP.
BookService.java

@RestController class BookService {@RequestMapping(value= "/book1", produces = MediaType.APPLICATION_JSON_VALUE)Book bookInfo1() {Book book = new Book();book.setBookName("Godan");book.setWriter("Premchand");return book;} }

When we access the URL http://localhost:8080/concretepage-1/book1?callback=functionCall, it will throw the response as

functionCall({"bookName":"Godan","writer":"Premchand"});

JSONP with @ResponseBody and ResponseEntity
Now find a controller in which we have created methods that will return @ResponseBody and ResponseEntity.

@Controller class BookController {@RequestMapping(value ="/book2", produces =MediaType.APPLICATION_JSON_VALUE )@ResponseBodyBook bookInfo2() {Book book = new Book();book.setBookName("Ramcharitmanas");book.setWriter("TulasiDas");return book;}@RequestMapping(value ="/book3", produces =MediaType.APPLICATION_JSON_VALUE )public ResponseEntity<Book> bookInfo3() {Book book = new Book();book.setBookName("Ramayan");book.setWriter("Valmiki");return ResponseEntity.accepted().body(book);} }

When we access the URL http://localhost:8080/concretepage-1/book2?callback=functionCall, we will get the output in browser as

functionCall({"bookName":"Ramcharitmanas","writer":"TulasiDas"});

And for the URL http://localhost:8080/concretepage-1/book3?callback=functionCall , the output will be

functionCall({"bookName":"Ramayan","writer":"Valmiki"});

JSONP Client Code
Now we will write client code which can be used in any other domain.
jsonptest.html

<html><head><script>function functionCall(data) { console.log(data.bookName);console.log(data.writer);console.log('-----------');}</script></head><body><!-- Using REST URL--><script src="http://localhost:8080/concretepage-1/book1?callback=functionCall" type="application/javascript"> </script><!--Using @ResponseBody --><script src="http://localhost:8080/concretepage-1/book2?callback=functionCall" type="application/javascript"> </script><!--Using ResponseEntity --><script src="http://localhost:8080/concretepage-1/book3?callback=functionCall" type="application/javascript"> </script></body> </html>

Run this page and check the output in console.




在Firefox,chrome,opera,safari,ie9,ie8等高級瀏覽器直接可以用JSON對象的stringify()和parse()方法。
JSON.stringify(obj)將JSON轉為字符串。JSON.parse(string)將字符串轉為JSON格式;
上面的轉換可以這么寫:
var a={"name":"tom","sex":"男","age":"24"};
var b='{"name":"Mike","sex":"女","age":"29"}';
var aToStr=JSON.stringify(a);
var bToObj=JSON.parse(b);
alert(typeof(aToStr)); //string
alert(typeof(bToObj));//object



代碼示例:

https://github.com/helloworldtang/cors-demo

參考:
http://www.cnblogs.com/softidea/p/3907113.html

http://blog.csdn.net/u010537398/article/details/52012548

https://en.wikipedia.org/wiki/JSONP

https://stackoverflow.com/questions/10323625/how-to-support-jsonp-with-spring-mvc-and-multiple-response-types

https://tonghuashuo.github.io/blog/jsonp.html

http://www.concretepage.com/spring-4/spring-4-mvc-jsonp-example-with-rest-responsebody-responseentity

http://blog.csdn.net/caiwenfeng_for_23/article/details/45300739

http://www.jianshu.com/p/983642ad125a

http://www.codesnoopy.com/2016/07/09/%E7%94%A8Spring-MVC-4%E5%AE%9E%E7%8E%B0jsonp%E8%B7%A8%E5%9F%9F%E8%B0%83%E7%94%A8/

https://my.oschina.net/u/130771/blog/52912

?

總結

以上是生活随笔為你收集整理的CORS 实战 专题的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。