Tuesday, February 19, 2013

Cross-domain communication problems


Cross-domain communication 


პრობლემა რიმლისათვისაც ბევრი framework არის დაწერილი, როგორებიცაა მგალითად easyxdm, YUI. მაგრამ საქმე გაცილებით გამარტივდა როდესაც HTML 5 თან გვაქვს უკვე საქმე. 


მაგალითად ავიღოთ 2 დომეინი A.net და B.net. გვინდა მათ შორის გვქონდეს კომუნიკაცია.

XmlHttpRequest ობიექტს ადევს   security  ბრაუზერებისაგან, რომელიც კრძალავს  მიწვდეს მონაცემებს სხვა სერვერზე. ეს კი  Ajax developer ებისთვის სერიოზული ლიმიტია.

წარმოვიდგინოთ გვინდა ასეთი სტრუქტორა. ჩვენ ფეიჯ  A.net ზე გვაქვს iframe რომელშიც არის B.net ის გვერდი. ახლა კი გვინდა კომუნიკაციები მათ შორის. მაგალითად , უმარტივესი, თუ დავაკლიკეთ iframe–ს შიგნით რაიმე ღილაკს, გვინდა A.net ის ფეიჯზე დაფიქსირდეეს და მათ შორის Request -Response კომუნიკაციები გავმართოთ.

ასეთი სტრუქტურები მრავლად არის პრაქტიკაში. მაგალითად Chrome Extension–ს რომ ვწერდი Gmail–ისთვის, მეილის გვერდზე როდესაც ვაწვებოდი Signe Document კნოპკას,  უნდა გამოსულიყო Iframe ჩემი სერვერის. აქ უნდა მქონოდა Listener ები გვერდებზე და Request-responze კომუნიკაციები ჩემ სერვლეტსა და extension -ს შორის.


HTML5-ს შემოთავაზებული გზა ასეთია , ვიძახებთ window.postMessage()-ს რომელსა ორი პარამეტრი გადაეცემა. 1 სტრუქტურა რაც გვინდა გადავცეთ და 2–ე არის მიმღები (ან * ყველასთვის);



  1. stuct=new Object();
  2. stuct.owner="admin";
  3. stuct.status="cancell";
  4. parent.postMessage(struct, "https://mail.google.com"
და მიმღები უსმენს მას:
  1. window.addEventListener("message", function( event ) {
  2. if ( event.data.status === "cancell" ) {
  3. console.log(event.origin)
  4. }
  5. }, false );
მაგალითად iframe ში რაღაცას რო დავაწვები, სერვერზე რო წამოვიდეს პასუხი:
  1. <!DOCTYPE HTML>
  2. <html>
  3. <head>
  4. <script>
  5. var send= function(){
  6. // Post message
  7. // from Iframe Page to domain A
  8. parent.postMessage("FROM IFRAME ","http://a.net");
  9. }
  10. </script>
  11. </head>
  12. <body>
  13. INSODE
  14. <button onclick="send()">Inside The iframe</button>
  15.  
  16. <script>
  17. // Listen from Domain A
  18. window.addEventListener('message', function(event) {
  19. console.log(event.data+' : '+event.origin) ;
  20. }, false);
  21.  
  22. </script>
  23. </body>
  24. </html>
  25.  
  26.  
  27. <!DOCTYPE HTML>
  28. <html>
  29. <head>
  30. <script>
  31. function sendCommand() {
  32. // post massage to domain B
  33. var receiver =
          document.getElementById('frameId').contentWindow;
  34. receiver.postMessage("MSG", 'http://b.net');
  35. }
  36.  
  37. function load (){
  38. // Leasten messages from Domain B
  39. window.addEventListener('message', function(event) {
  40. console.log(event.data+' : '+event.origin) ;
  41. return;
  42. }, false);
  43. }
  44. </script>
  45. </head>
  46. <body onload="load()">
  47. <iframe id="frameId" src="http://b.net/2.html" onload="sendCommand();"> No Frame!</iframe>
  48. <button onclick="sendCommand()">OutSide The Frame</button>
  49. </body>
  50. </html>
რაც შეეხება Request-Response–ბს. ჰედერში მოგიწევთ Access-Control-Allow-Origin ის ჩამატება.

მაგალითად სერვლეტებში
  1. protected void doPost(HttpServletRequest request, HttpServletResponse response) {
  2. response.addHeader("Access-Control-Allow-Origin","UR");
  3. ...
  4. }
 Ajax–ში თუ გვინდა ჰედერში ასე ჩავამატებთ.
  1. var xhr = new XMLHttpRequest();
  2. xhr.open("GET", url, true);
  3. xhr.responseType = "arraybuffer";
  4. xhr.setRequestHeader('Access-Control-Allow-Origin', 'URL');
XDomainRequest object  არის, რომელიც IE სთვის. CORS–ს გვთავაზობს Firefox. რომელიც ყველა ბრაუზერში კარგადაა.


  1. function createCORSRequest(method, url){
  2. var xhr = new XMLHttpRequest();
  3. if ("withCredentials" in xhr){
  4. xhr.open(method, url, true);
  5. } else if (typeof XDomainRequest != "undefined"){
  6. xhr = new XDomainRequest();
  7. xhr.open(method, url);
  8. } else {
  9. xhr = null;
  10. }
  11. return xhr;
  12. }
თორემ გამოვარდება ბრაუზერისგან შეცდომა:
XMLHttpRequest cannot load http://b.net/.../. Origin https://a.net is not allowed by Access-Control-Allow-Origin.


No comments:

Post a Comment