2017-10-29 8 views
2

vert.xでCORSの設定を理解しようとしています。私はthis github repositoryの例をCORSセクションの下に見つけました。私が試したときにPOSTの例がうまくいくように見えました(preflight.html)。私も自分のプロジェクトの一つでGET(nopreflight.html)を使う必要があるので、私は悪い結果を得ている例を修正しようとしました。これは私が今持っているものです。CORS(Cross-Origin Resource Sharing)を許可するようにvert.xサーバを正しく設定してください

Server.java

package io.vertx.example.web.cors; 
import io.vertx.core.AbstractVerticle; 
import io.vertx.core.MultiMap; 
import io.vertx.core.http.HttpMethod; 
import io.vertx.example.util.Runner; 
import io.vertx.ext.web.Router; 
import io.vertx.ext.web.handler.CorsHandler; 
import io.vertx.ext.web.handler.StaticHandler; 

import java.util.Map; 
/* 
* @author <a href="mailto:[email protected]">Paulo Lopes</a> 
*/ 
public class Server extends AbstractVerticle { 

    // Convenience method so you can run it in your IDE 
    public static void main(String[] args) { 
     Runner.runExample(Server.class); 
    } 

    @Override 
    public void start() throws Exception { 

     Router router = Router.router(vertx); 

     router.route().handler(CorsHandler.create("*") 
          .allowedMethod(HttpMethod.GET) 
          .allowedMethod(HttpMethod.POST) 
          .allowedMethod(HttpMethod.OPTIONS) 
          .allowedHeader("Access-Control-Request-Method") 
          .allowedHeader("Access-Control-Allow-Credentials") 
          .allowedHeader("Access-Control-Allow-Origin") 
          .allowedHeader("Access-Control-Allow-Headers") 
          .allowedHeader("X-PINGARUNER") 
          .allowedHeader("Content-Type")); 

     router.get("/access-control-with-get").handler(ctx -> { 
      ctx.response().setChunked(true); 

      MultiMap headers = ctx.request().headers(); 
      /*for (String key : headers.names()) { 
       ctx.response().write(key); 
       ctx.response().write(headers.get(key)); 
       ctx.response().write("\n"); 
      }*/ 
      ctx.response().write("response "); 
      ctx.response().end(); 
     }); 

     router.post("/access-control-with-post-preflight").handler(ctx -> { ctx.response().setChunked(true); 

      MultiMap headers = ctx.request().headers(); 
      /*for (String key : headers.names()) { 
       ctx.response().write(key); 
       ctx.response().write(headers.get(key)); 
       ctx.response().write("\n"); 
      }*/ 
      ctx.response().write("response "); 
      ctx.response().end(); 
     }); 

     // Serve the static resources 
     router.route().handler(StaticHandler.create()); 

     vertx.createHttpServer() 
     .requestHandler(router::accept) 
     .listen(8080); 
    } 
} 

nopreflight.html

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<title>Simple use of Cross-Site XMLHttpRequest (Using Access Control)</title> 
<script type="text/javascript"> 
     //<![CDATA[ 

     var invocation = new XMLHttpRequest(); 
     var url = 'http://localhost:8080/access-control-with-get/'; 
     var invocationHistoryText; 
     var body = '<?xml version="1.0"?><person><name>Arun</name></person>'; 

     function callOtherDomain(){ 
      if(invocation) 
      { 
       invocation.open('GET', url, true); 
       //invocation.setRequestHeader('X-PINGARUNER', 'pingpong'); 
       invocation.setRequestHeader('Content-Type', 'application/xml'); 
       invocation.onreadystatechange = handler; 
       invocation.send(); 
      } 
      else 
      { 
       invocationHistoryText = "No Invocation TookPlace At All"; 
       var textNode = document.createTextNode(invocationHistoryText); 
       var textDiv = document.getElementById("textDiv"); 
       textDiv.appendChild(textNode); 
      } 

     } 
     function handler() 
     { 
      if (invocation.readyState == 4) 
      { 
       if (invocation.status == 200) 
       { 
        var response = invocation.responseXML; 
        //var invocationHistory = response.getElementsByTagName('invocationHistory').item(0).firstChild.data; 
        invocationHistoryText = document.createTextNode(response); 
        var textDiv = document.getElementById("textDiv"); 
        textDiv.appendChild(invocationHistoryText); 

       } 
       else 
        alert("Invocation Errors Occured " + invocation.readyState + " and the status is " + invocation.status); 
      } 
      else 
       console.log("currently the application is at " + invocation.readyState); 
     } 
     //]]> 


    </script> 
</head> 
<body> 
<form id="controlsToInvoke" action=""> 
    <p> 
     <input type="button" value="Click to Invoke Another Site" onclick="callOtherDomain()" /> 
    </p> 
</form> 
<p id="intro"> 
    This page basically makes invocations to another domain using cross-site XMLHttpRequest mitigated by Access Control. This is the simple scenario that is <em>NOT</em> preflighted, and the invocation to a resource on another domain takes place using a simple HTTP GET. 
</p> 
<div id="textDiv"> 
    This XHTML document invokes another resource using cross-site XHR. 
</div> 
</body> 
</html> 

preflight.html

<?xml version="1.0" encoding="UTF-8"?> 
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> 
    <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> 
<head> 
<title>Simple use of Cross-Site XMLHttpRequest (Using Access Control)</title> 
<script type="text/javascript"> 
     //<![CDATA[ 

     var invocation = new XMLHttpRequest(); 
     var url = 'http://localhost:8080/access-control-with-post-preflight/'; 
     var invocationHistoryText; 
     var body = '<?xml version="1.0"?><person><name>Arun</name></person>'; 

     function callOtherDomain(){ 
      if(invocation) 
      { 
       invocation.open('POST', url, true); 
       invocation.setRequestHeader('X-PINGARUNER', 'pingpong'); 
       invocation.setRequestHeader('Content-Type', 'application/xml'); 
       invocation.onreadystatechange = handler; 
       invocation.send(); 
      } 
      else 
      { 
       invocationHistoryText = "No Invocation TookPlace At All"; 
       var textNode = document.createTextNode(invocationHistoryText); 
       var textDiv = document.getElementById("textDiv"); 
       textDiv.appendChild(textNode); 
      } 

     } 
     function handler() 
     { 
      if (invocation.readyState == 4) 
      { 
       if (invocation.status == 200) 
       { 
        var response = invocation.responseText; 
        //var invocationHistory = response.getElementsByTagName('invocationHistory').item(0).firstChild.data; 
        invocationHistoryText = document.createTextNode(response); 
        var textDiv = document.getElementById("textDiv"); 
        textDiv.appendChild(invocationHistoryText); 

       } 
       else 
       { 
        alert("Invocation Errors Occured " + invocation.readyState + " and the status is " + invocation.status); 
       } 
      } 
      else 
      { 
       console.log("currently the application is at " + invocation.readyState); 
      } 
     } 
     //]]> 


    </script> 
</head> 
<body> 
<form id="controlsToInvoke" action=""> 
    <p> 
     <input type="button" value="Click to Invoke Another Site" onclick="callOtherDomain()" /> 
    </p> 
</form> 
<p id="intro"> 
    This page POSTs XML data to another domain using cross-site XMLHttpRequest mitigated by Access Control. This is the preflight scenario and the invocation to a resource on another domain takes place using first an OPTIONS request, then an actual POST request. 
</p> 
<div id="textDiv"> 
    This XHTML document POSTs to another resource using cross-site XHR. If you get a response back, the content of that response should reflect what you POSTed. 
</div> 
</body> 
</html> 

編集:提案Iへ 感謝Server.javaのコードを変更して明確にしました。問題はハンマーf nopreflight.htmlファイルのunction。これが私たちのために、この後の

Router router = Router.router(vertx); 

    Set<String> allowedHeaders = new HashSet<>(); 
    allowedHeaders.add("x-requested-with"); 
    allowedHeaders.add("Access-Control-Allow-Origin"); 
    allowedHeaders.add("origin"); 
    allowedHeaders.add("Content-Type"); 
    allowedHeaders.add("accept"); 

    Set<HttpMethod> allowedMethods = new HashSet<>(); 
    allowedMethods.add(HttpMethod.GET); 
    allowedMethods.add(HttpMethod.POST); 
    allowedMethods.add(HttpMethod.DELETE); 
    allowedMethods.add(HttpMethod.PATCH); 
    allowedMethods.add(HttpMethod.OPTIONS); 
    allowedMethods.add(HttpMethod.PUT); 

    router.route().handler(CorsHandler.create("*") 
      .allowedHeaders(allowedHeaders) 
      .allowedMethods(allowedMethods)); 

    router.get("/").handler(context1 -> { 
     HttpServerResponse httpServerResponse = context1.response(); 
     httpServerResponse.putHeader("content-type", "text/html").end("<h1>Success</h1>"); 
    }); 

正常に動作しているようだ

<script type="text/javascript"> 

    var xhttp = new XMLHttpRequest(); 
    var url = 'http://localhost:8080/access-control-with-get/'; 
    var invocationHistoryText; 

    function callOtherDomain() { 
     var xhttp = new XMLHttpRequest(); 
     xhttp.onreadystatechange = function() { 
      if (this.readyState == 4 && this.status == 200) { 
       document.getElementById("textDiv").appendChild(document.createTextNode(xhttp.responseText)); 
      } 
     }; 
     xhttp.open("GET", url, true); 
     xhttp.send(); 
    } 

</script> 

答えて

0

nopreflight.html EDITED

EDITED Server.java

public class Server extends AbstractVerticle { 

// Convenience method so you can run it in your IDE 
public static void main(String[] args) { 
    Runner.runExample(Server.class); 
} 

@Override 
public void start() throws Exception { 

    Router router = Router.router(vertx); 

    Set<String> allowedHeaders = new HashSet<>(); 
    allowedHeaders.add("x-requested-with"); 
    allowedHeaders.add("Access-Control-Allow-Origin"); 
    allowedHeaders.add("origin"); 
    allowedHeaders.add("Content-Type"); 
    allowedHeaders.add("accept"); 
    allowedHeaders.add("X-PINGARUNER"); 

    Set<HttpMethod> allowedMethods = new HashSet<>(); 
    allowedMethods.add(HttpMethod.GET); 
    allowedMethods.add(HttpMethod.POST); 
    allowedMethods.add(HttpMethod.DELETE); 
    allowedMethods.add(HttpMethod.PATCH); 
    allowedMethods.add(HttpMethod.OPTIONS); 
    allowedMethods.add(HttpMethod.PUT); 


    router.route().handler(CorsHandler.create("*") 
     .allowedHeaders(allowedHeaders) 
     .allowedMethods(allowedMethods)); 

    router.get("/access-control-with-get").handler(ctx -> { 
     HttpServerResponse httpServerResponse = ctx.response(); 
     httpServerResponse.putHeader("content-type", "text/html").end("<h1>Success</h1>"); 
    }); 

を次のように私はこの問題を解決しますhttpserverを作成するとうまくいくはずです。

+0

あなたの実装では、まだ "null"という応答がサーバーから得られます。多分問題は私のnopreflight.htmlにありますか?明らかに私は 'router.get("/")ハンドラ(context1 - > { ... })を変更しました。 router.get( "/ access-control-with-get")。ハンドラ(context1 - > { ... });それ以外の場合は動作していませんでした。 –

関連する問題