จะเปิดใช้งานคำขอข้ามโดเมนบนบริการเว็บ JAX-RS ได้อย่างไร

ฉันพัฒนาชุดบริการเว็บเพื่อการพักผ่อน ฉันไม่สามารถเรียกวิธีการเหล่านี้จากไคลเอนต์ระยะไกลได้เนื่องจากข้อผิดพลาด No 'Access-Control-Allow-Origin' header is present on the requested resource.

บริการทำงานได้อย่างสมบูรณ์บน localhost มีการเปลี่ยนแปลงหรือการกำหนดค่าที่ต้องทำบนฝั่งเซิร์ฟเวอร์เพื่อแก้ไขปัญหาหรือไม่ นั่นคือเพื่อเปิดใช้งานคำขอข้ามโดเมน

ฉันใช้ WildFly 8, JavaEE 7


person Naili    schedule 03.05.2014    source แหล่งที่มา
comment
คุณสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ CORS ได้ที่นี่: html5rocks.com/en/tutorials/cors คุณสามารถเรียนรู้วิธีเพิ่มการรองรับ CORS ให้กับ JAX-RS ได้ที่นี่: cxf.apache org/docs/jax-rs-cors.html   -  person monsur    schedule 04.05.2014
comment
มีประโยชน์ แต่ฉันกำลังมองหาวิธีแก้ปัญหาโดยไม่ต้องแก้ไขโค้ดไคลเอนต์   -  person Naili    schedule 04.05.2014
comment
คำถามของคุณขอให้มีการเปลี่ยนแปลงฝั่งเซิร์ฟเวอร์ การเปลี่ยนแปลง CORS ส่วนใหญ่เกิดขึ้นที่ฝั่งเซิร์ฟเวอร์ มีการเปลี่ยนแปลงที่จำเป็นในไคลเอนต์เพียงเล็กน้อย (ถ้ามี)   -  person monsur    schedule 04.05.2014


คำตอบ (9)


ฉันสงสัยในสิ่งเดียวกัน ดังนั้นหลังจากการค้นคว้าเล็กน้อย ฉันพบว่าวิธีที่ง่ายที่สุดคือใช้ JAX-RS ContainerResponseFilter เพื่อเพิ่มส่วนหัว CORS ที่เกี่ยวข้อง ด้วยวิธีนี้คุณไม่จำเป็นต้องแทนที่สแต็กบริการเว็บทั้งหมดด้วย CXF (Wildfly ใช้ CXF เป็นรูปแบบบางอย่าง แต่ดูเหมือนว่าจะใช้กับ JAX-RS อาจเป็นเพียง JAX-WS เท่านั้น)

ไม่ว่าคุณจะใช้ตัวกรองนี้หรือไม่ก็ตาม ตัวกรองจะเพิ่มส่วนหัวให้กับทุกบริการเว็บ REST

package com.yourdomain.package;

import java.io.IOException;

import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerResponseContext;
import javax.ws.rs.container.ContainerResponseFilter;
import javax.ws.rs.ext.Provider;

@Provider
public class CORSFilter implements ContainerResponseFilter {

   @Override
   public void filter(final ContainerRequestContext requestContext,
                      final ContainerResponseContext cres) throws IOException {
      cres.getHeaders().add("Access-Control-Allow-Origin", "*");
      cres.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization");
      cres.getHeaders().add("Access-Control-Allow-Credentials", "true");
      cres.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
      cres.getHeaders().add("Access-Control-Max-Age", "1209600");
   }

}

จากนั้นเมื่อฉันทดสอบด้วย curl การตอบสนองก็มีส่วนหัว CORS:

$ curl -D - "http://localhost:8080/rest/test"
HTTP/1.1 200 OK
X-Powered-By: Undertow 1
Access-Control-Allow-Headers: origin, content-type, accept, authorization
Server: Wildfly 8
Date: Tue, 13 May 2014 12:30:00 GMT
Connection: keep-alive
Access-Control-Allow-Origin: *
Access-Control-Allow-Credentials: true
Transfer-Encoding: chunked
Content-Type: application/json
Access-Control-Max-Age: 1209600
Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS, HEAD

ความเข้าใจของฉันคือมันเป็นคำอธิบายประกอบ @Provider ที่บอกให้รันไทม์ JAX-RS ใช้ตัวกรอง หากไม่มีคำอธิบายประกอบก็ไม่มีอะไรเกิดขึ้น

ฉันมีแนวคิดเกี่ยวกับการใช้ ContainerResponseFilter จาก ตัวอย่างเสื้อแข่ง

person Joel Pearson    schedule 13.05.2014
comment
ใช่ ฉันใช้วิธีแก้ปัญหาแบบเดียวกับที่คุณโพสต์ที่นี่ แต่ฉันเชื่อว่าเรากำลังสร้างปัญหาด้านความปลอดภัยโดยการอนุญาตการเชื่อมต่อข้ามโดเมนทุกครั้ง - person Naili; 13.05.2014
comment
ใช่ นั่นเป็นเรื่องจริงหากบริการเว็บ REST ของคุณใช้คุกกี้เพื่อความปลอดภัย แต่ถ้าคุณเพียงพยายามสร้างบริการเว็บ REST สาธารณะก็ไม่มีปัญหาด้านความปลอดภัย คุณไม่ได้พูดถึงในคำถามของคุณหากคุณต้องการเพียง 1 โดเมนในการทำงานเช่น services.yourdomain ตัวอย่างหรือทุกโดเมน - person Joel Pearson; 14.05.2014
comment
หากคุณวางแผนที่จะเพิ่มเฉพาะโฮสต์เฉพาะแทน * อย่าลืมเพิ่มพอร์ตด้วย - person ACV; 08.04.2015
comment
@JoelPearson คุณช่วยบอกวิธีกำหนดค่าตัวกรองนี้ได้ไหม ฉันควรทำใน web.xml หรือไม่ - person Jay; 09.09.2015
comment
@Jay ใช้คำอธิบายประกอบ @ Provider ดังนั้นตราบใดที่คุณเปิดใช้งาน CDI สำหรับหู / สงครามของคุณก็ไม่จำเป็นต้องกำหนดค่าเพิ่มเติม - person Joel Pearson; 11.09.2015
comment
+1 สำหรับคำอธิบายประกอบ @Provider ฉันก็ดูตัวอย่างออนไลน์เหมือนกัน แต่ก็พลาดส่วนสำคัญนี้ไป! - person bradimus; 02.10.2015
comment
ฉันกำลังใช้บริการบนเซิร์ฟเวอร์ท่าเทียบเรือพร้อมคอนเทนเนอร์เซิร์ฟเล็ตเสื้อเจอร์ซีย์ ในกรณีนี้ การมี @Provider เท่านั้นไม่เพียงพอ คลาส CORSFilter จะต้องลงทะเบียนเป็นพารามิเตอร์ init ของ jersey servlet ดังนี้: jerseyServlet.setInitParameter( "jersey.config.server.provider.classnames", MyService.class.getCanonicalName() + ", org.glassfish.jersey.media.multipart.MultiPartFeature, " + CORSFilter.class.getCanonicalName()) - person Ashok; 01.12.2015
comment
@Ashok คำถามนี้เกี่ยวกับ Wildfly 8 และ JEE 7 ไม่ใช่ท่าเทียบเรือ/เสื้อแข่ง ดังนั้นหากคุณมีคำถามอื่น คุณควรสร้างคำถามอื่น เนื่องจากโซลูชันนี้จะไม่เกี่ยวข้องกับคุณ - person Joel Pearson; 02.12.2015
comment
@Joel Pearson เห็นด้วย ฉันเจอคำถามนี้ผ่านการค้นหาของ Google เพื่อเปิดใช้งาน CORS ใน jax-rs แค่คิดว่ามันอาจเป็นประโยชน์กับผู้อื่นที่เข้ามาในหน้านี้เช่นเดียวกัน อย่างไรก็ตาม คำตอบที่ได้รับการยอมรับดูเหมือนจะไม่ได้แนะนำอะไรที่เฉพาะเจาะจงกับ wildfly หรือ jee7 บางทีฉันอาจพลาดลิงค์ไป? นี่เป็นวิธีแก้ปัญหาที่เหมาะกับฉันกับท่าเทียบเรือ+เสื้อแข่ง และขอบคุณที่โพสต์ไว้ - person Ashok; 02.12.2015
comment
@Ashok จริงอาจไม่ใช่ JEE 7 ดูเหมือนว่าคำอธิบายประกอบของผู้ให้บริการมีอยู่ใน JEE 6: docs.oracle.com/javaee/6/api/index.html?javax/ws/rs/ext/ สิ่งที่ทำให้ Wildfly คือ ความจริงคุณต้องมี CDI เพื่อให้มันทำงานเหมือนเดิม แต่เป็นไปได้ว่าจะทำงานในคอนเทนเนอร์ JEE 6 ใดก็ได้เนื่องจากไม่ได้อ้างอิงถึง Wildfly API โดยตรง เป็นเรื่องน่าสนใจที่คุณยังคงสามารถใช้งาน JAX-RS ภายนอก JEE ได้ ข้อมูลที่น่าสนใจขอบคุณ - person Joel Pearson; 03.12.2015
comment
Access-Control-Allow-Credentials: true บรรทัดนี้ขัดแย้งกับ "Access-Control-Allow-Origin", "*" จริงๆ เนื่องจากอาจเป็นปัญหาด้านความปลอดภัย หรือ (อย่างน้อยใน Chrome) ก็ถูกปฏิเสธ หากคุณต้องการอนุญาตข้อมูลประจำตัว คุณจะต้องระบุต้นทางที่เจาะจง ไม่ใช่ไวด์การ์ด - person Stijn de Witt; 02.02.2016
comment
ขั้นแรกให้รับต้นทางของคำขอ: String origin = requestContext.getHeaderString("origin"); จากนั้น (เมื่อ origin !== null) ให้ใช้ต้นทางนั้นโดยใช้ไวด์การ์ด: cres.getHeaders().add("Access-Control-Allow-Origin", origin); หาก API ของคุณใช้คุกกี้สำหรับการตรวจสอบสิทธิ์ (เช่น เมื่อใช้การตรวจสอบสิทธิ์ที่จัดการโดยคอนเทนเนอร์) ให้ตรวจสอบต้นทางกับรายการที่อนุญาตพิเศษของต้นทางที่อนุญาตก่อนตั้งค่าส่วนหัว CORS - person Stijn de Witt; 15.02.2016
comment
ขอบคุณมาก สำหรับผู้ที่สงสัยว่าเมื่อใดควรใส่โค้ดนี้ คุณเพียงแค่ต้องมีโค้ดนี้ในแพ็คเกจ org.yourdomain.rest ของคุณ หากคุณใช้ wildfly 10 - person netto; 17.10.2016
comment
เราประสบปัญหา เนื่องจากผู้ให้บริการไม่ได้ลงทะเบียนตามค่าเริ่มต้น และคำถามต่อไปนี้ช่วยได้: stackoverflow.com/questions/32328012/ - person boutta; 23.11.2017
comment
@Naili มีปัญหาด้านความปลอดภัยหากแอปพลิเคชันของคุณจำกัดการเข้าถึงตามหมายเลข IP (ซึ่งเป็นแนวทางปฏิบัติที่แย่มาก) เฉพาะในกรณีนี้ไซต์ที่เป็นอันตรายเท่านั้นที่สามารถเข้าถึงข้อมูลที่ไม่สามารถเรียกคืนได้ ในสถานการณ์อื่นๆ ทั้งหมด เนื่องจากไม่อนุญาตให้ใช้ข้อมูลประจำตัว (ตามที่ระบุไว้โดย Stijn de Witt) จึงไม่มีปัญหาด้านความปลอดภัย - person Reto Gmür; 27.02.2018
comment
สิ่งนี้ได้ผลสำหรับฉันเมื่อปรับใช้กับ JBoss EAP 7.1 เฉพาะในกรณีที่ฉันเพิ่มอินสแตนซ์ CORSFilter อย่างชัดเจนใน JaxRsApplication singletons @Provider ด้วยตัวมันเองไม่ได้ผลสำหรับฉัน - person Marcus Junius Brutus; 29.01.2020
comment
ฉันสามารถลบ/ปิดใช้งานส่วนหัวการตอบกลับเริ่มต้น เช่น Server: Wildfly 8 ได้หรือไม่ - person Ahmad Nadeem; 11.05.2020
comment
นี่ไม่เพียงพอ หากมีการตรวจสอบสิทธิ์ คุณต้องตรวจสอบให้แน่ใจว่าไม่ได้ใช้กับคำขอ OPTIONS โดยควรเพิ่มตัวจัดการ @OPTIONS @Path("{path : .*}") ต่อ nemesisfixx คำตอบ - person Jan Hudec; 14.08.2020

ฉันประสบปัญหาที่คล้ายกัน และได้ลองใช้โซลูชันของ @Alex Petty แต่นอกเหนือจากต้องตั้งค่าส่วนหัว CORS ในแต่ละตำแหน่งข้อมูล JAX-RS ในชั้นเรียนของฉัน เช่น:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getMemberList() {
    List<Member> memberList = memberDao.listMembers();
    members.addAll(memberList);
    return Response
            .status(200)
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .entity(memberList)
            .build();
}

ฉันต้องกำหนดจุดสิ้นสุด catch-all OPTIONS เพิ่มเติมที่จะส่งคืนส่วนหัว CORS สำหรับคำขอ OPTIONS อื่น ๆ ในชั้นเรียน และด้วยเหตุนี้จึงจับจุดสิ้นสุดของการเรียงลำดับทั้งหมด:

@OPTIONS
@Path("{path : .*}")
public Response options() {
    return Response.ok("")
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .build();
}

หลังจากทำเช่นนี้แล้ว ฉันจึงสามารถใช้จุดสิ้นสุด JAX-RS API ของฉันจากไคลเอนต์ Jquery Ajax บนโดเมนหรือโฮสต์อื่นได้อย่างถูกต้อง

person nemesisfixx    schedule 11.03.2015
comment
ฉันมีปัญหาแปลกๆ ส่วนหัวการตอบกลับ (.header(SOME_HEADER,SOME_HEADER) ที่ฉันตั้งค่าไว้ไม่ได้รับการเรนเดอร์ใน UI แบบผยองใน Google Chrome, Mozilla แต่ใน IE 11 ฉันได้ตรวจสอบแล้วว่าส่วนหัวการตอบกลับนี้กำลังมาถึงเบราว์เซอร์ (ในส่วนหัวการตอบกลับคอนโซลของเครื่องมือนักพัฒนาซอฟต์แวร์ ) แต่สิ่งเดียวกันไม่ได้รับการเรนเดอร์ใน Swagger UI - person Debaprasad Jana; 28.12.2015
comment
นั่นไม่ถูกต้อง คุณต้องใช้ตัวกรอง ใช้ตัวกรองเมื่อคุณต้องการกรองและ/หรือแก้ไขคำขอตามเงื่อนไขเฉพาะ ใช้ Servlet เมื่อคุณต้องการควบคุม ประมวลผลล่วงหน้า และ/หรือ ประมวลผลคำขอภายหลัง docs.oracle.com/javaee/6/tutorial/doc/bnagb HTML - person max_dev; 11.06.2016
comment
ฉันเพิ่งเพิ่ม .header(Access-Control-Allow-Origin, *) และใช้งานได้ - person Pini Cheyni; 06.05.2017

ฉันพบวิธีที่ง่ายยิ่งขึ้น (เฉพาะ RestEasy) ในการเปิดใช้งาน CORS บน Wildfly โดยไม่ต้องใช้ตัวกรอง และตำแหน่งที่คุณสามารถควบคุมการกำหนดค่าส่วนหัวการตอบสนอง API ของคุณในระดับทรัพยากร

ตัวอย่างเช่น:

@GET
@Produces(MediaType.APPLICATION_JSON)
public Response getMemberList() {
    List<Member> memberList = memberDao.listMembers();
    members.addAll(memberList);
    return Response
            .status(200)
            .header("Access-Control-Allow-Origin", "*")
            .header("Access-Control-Allow-Headers", "origin, content-type, accept, authorization")
            .header("Access-Control-Allow-Credentials", "true")
            .header("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
            .header("Access-Control-Max-Age", "1209600")
            .entity(memberList)
            .build();
}
person Alex Petty    schedule 08.08.2014
comment
ขอบคุณ ฉันไม่สามารถรับคลาส 'javax.ws.rs.container' ได้ (ทำไมต้องเป็นเวอร์ชัน JAX-RS อื่น) และโซลูชันของคุณก็ใช้ได้ดี - person Guildenstern70; 12.09.2014
comment
วิธีนี้ใช้ได้กับ GET เท่านั้น เมื่อลองใช้ POST (จากไคลเอนต์) เกิดข้อผิดพลาดเดียวกัน ฉันยังคงพยายามค้นหาวิธีแก้ปัญหานี้ เนื่องจากที่มาของฉันจะแตกต่างกันไปตลอดเวลา - person Francisco Souza; 10.09.2015
comment
สิ่งนี้จะไม่มีวันได้ผล มันผิด CORS เรียกวิธี HTTP OPTIONS ก่อนที่จะเรียก GET, POST หรืออะไรก็ตาม รายการส่วนหัวจะต้องมีการกำหนดภายในวิธี OPTIONS หากไม่เป็นเช่นนั้น เบราว์เซอร์จะไม่ยอมรับ การกรองคำขอ HTTP เป็นวิธีที่ดีที่สุดในการทำสิ่งนี้ อีกประการหนึ่ง หากคุณใช้เซิร์ฟเวอร์ HTTP ร้ายแรง เช่น Apache รายการ Access-Control-Allow-Origin, * จะต้องกระจัดกระจาย และเบราว์เซอร์จะไม่ยอมอนุญาต คุณต้องเพิ่ม DNS ที่อนุญาตโดยเฉพาะ เช่น การควบคุมการเข้าถึง-อนุญาต-แหล่งกำเนิด: my.domain.com - person jbrios777; 10.08.2016
comment
แต่ถ้าคุณมีวิธีการมากกว่า 100 วิธี... วิธีที่ดีกว่าคือการใช้ตัวกรอง - person ACV; 30.08.2016
comment
@Paul Samsotha ให้คำตอบที่สมบูรณ์พร้อมคำอธิบายที่ถูกต้องสำหรับคำขอก่อนการบินและนี่คือลิงค์ - stackoverflow.com/a/ 28067653/3257644 - person Mahesh; 17.02.2020

ฉันโชคดีในการกำหนดค่าการแบ่งปันทรัพยากรข้ามแหล่งกำเนิด (CORS) สำหรับ API ของฉัน (บน Wildfly) โดยใช้ lib นี้:

<dependency>
<groupId>com.thetransactioncompany</groupId>
<artifactId>cors-filter</artifactId>
<version>2.1</version>
</dependency>

มันง่ายมากที่จะติดตั้ง เพียงเพิ่มการพึ่งพาข้างต้นให้กับ pom ของคุณ จากนั้นเพิ่มการกำหนดค่าต่อไปนี้ในส่วน webapp ของไฟล์ web.xml ของคุณ

<filter>
    <filter-name>CORS</filter-name>
    <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>

    <init-param>
        <param-name>cors.allowGenericHttpRequests</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowOrigin</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.allowSubdomains</param-name>
        <param-value>false</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedMethods</param-name>
        <param-value>GET, HEAD, POST, DELETE, OPTIONS</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportedHeaders</param-name>
        <param-value>*</param-value>
    </init-param>

    <init-param>
        <param-name>cors.supportsCredentials</param-name>
        <param-value>true</param-value>
    </init-param>

    <init-param>
        <param-name>cors.maxAge</param-name>
        <param-value>3600</param-value>
    </init-param>

</filter>

<filter-mapping>
    <!-- CORS Filter mapping -->
    <filter-name>CORS</filter-name>
    <url-pattern>*</url-pattern>
</filter-mapping>

คุณยังสามารถกำหนดค่าด้วยไฟล์คุณสมบัติแทนได้หากต้องการ lib นี้ทำงานได้อย่างมีเสน่ห์และให้ความยืดหยุ่นในการกำหนดค่าอย่างมาก!

person Alex Petty    schedule 27.06.2014
comment
ฉันต้องการลองสิ่งนี้แต่มีข้อผิดพลาดในคอนโซลบันทึกของฉัน: The 'Access-Control-Allow-Origin' header contains multiple values 'http://127.0.0.1, *', but only one is allowed. แนวคิดที่ต้องเปลี่ยนแปลงบน web.xml เพื่อให้ถูกต้องคืออะไร - person Ayyoub; 22.07.2015
comment
ฉันลองสิ่งนี้แล้ว แต่ไม่เห็นสิ่งนี้เพิ่มเข้าไปในส่วนหัว - person Jay; 09.09.2015

ไม่มีคำตอบอื่นใดที่เหมาะกับฉัน แต่สิ่งนี้ได้ผล:

import javax.ws.rs.core.Response;

จากนั้นเปลี่ยนประเภทการส่งคืนของวิธีการบริการเป็น Response และเปลี่ยนคำสั่ง return เป็น:

return Response.ok(resp).header("Access-Control-Allow-Origin", "*").build();

โดยที่ resp คือออบเจ็กต์ตอบกลับดั้งเดิม

person Alex R    schedule 18.07.2015
comment
ใช้งานได้เฉพาะเมื่อเป็นคำขอธรรมดาเท่านั้น นั่นคือถ้าคำขอคือ GET หรือ POST และส่วนหัวของคำขอนั้นเรียบง่าย (ส่วนหัวแบบง่ายเท่านั้นคือ Accept, Accept-Language, Content-Language, Content-Type= application/x-www-form-urlencoded, multipart/form-data, ข้อความ/ธรรมดา) มิฉะนั้นเบราว์เซอร์จะส่งคำขอ OPTIONS ก่อนคำขอจริง - person Ranuka; 03.12.2016

คุณยังสามารถใช้ javax.ws.rs.core.Feature ตามด้านล่างเพื่อใช้งาน CORS

import javax.ws.rs.core.Feature;
import javax.ws.rs.core.FeatureContext;
import javax.ws.rs.ext.Provider;
import org.jboss.resteasy.plugins.interceptors.CorsFilter;

@Provider
 public class CorsFeature implements Feature {

  @Override
  public boolean configure(FeatureContext context) {
    CorsFilter corsFilter = new CorsFilter();
    corsFilter.getAllowedOrigins().add("*");
    context.register(corsFilter);
    return true;
 }

}
person Ranuka    schedule 06.12.2016

วิธีแก้ปัญหานี้จะเพิ่มส่วนหัวในการตอบกลับ ใน spring หรือ spring boot จะมีคำอธิบายประกอบ แต่ในระบบเก่า อาจไม่มีคำอธิบายประกอบ คุณสามารถแก้ไขได้ด้วยการเพิ่มตัวกรอง

คลาสตัวกรอง:

package com.koushik.restapis.intercepter;

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;


public class RestCorsFilter implements Filter {

    @Override
    public void destroy() {
    enter code here
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
            throws IOException, ServletException {
    
        HttpServletResponse resp = (HttpServletResponse) response;
        resp.addHeader("Access-Control-Allow-Origin", "*");
        resp.addHeader("Access-Control-Allow-Headers", "*");
        resp.addHeader("Access-Control-Allow-Methods", "*");
        
        chain.doFilter(request, resp);
        
    }

    @Override
    public void init(FilterConfig arg0) throws ServletException {
        
    }

}

เว็บ.xml

  <filter>
    <filter-name>RestCorsFilter</filter-name>
    <filter-class>com.koushik.restapis.RestCorsFilter</filter-class>
  </filter>
    <filter-mapping>
    <filter-name>RestCorsFilter</filter-name>
    <url-pattern>/apis/*</url-pattern>
  </filter-mapping>
person 404Koushik    schedule 05.09.2020

คำตอบของ @Joel Pearson ช่วยได้ แต่สำหรับคนที่ยังใหม่กับ JAX-RS เช่นฉันและกำลังใช้บริการบน Tomcat โดยการกำหนดค่า web.xml ควรระมัดระวังในขณะที่สร้างคลาสและวางไว้ที่ใดก็ได้ในโครงการ ดูแพ็คเกจที่คุณระบุไว้ด้านล่างสำหรับเสื้อแข่งและสร้างคลาสตัวกรองนี้ที่นั่น วิธีนั้นมันได้ผลสำหรับฉัน

person Novice_JS    schedule 14.09.2018

เพียงเพื่อเพิ่มบางสิ่งในการตอบกลับอื่น ๆ การอนุญาต * เป็นอันตรายนิดหน่อย สิ่งที่สามารถทำได้คือการกำหนดค่าฐานข้อมูลต้นทางที่อนุญาต (อาจเป็นไฟล์ก็ได้)

จากนั้นเมื่อคำขอมาถึง คุณสามารถทำได้:

// this will return you the origin 
String[] referers = requestContext.getHeaders().get("referer")

// then search in your DB if the origin is allowed
if (referers != null && referers.lenght == 1 && isAllowedOriging(referers[0])) {
        containerResponseContext.getHeaders().add("Access-Control-Allow-Origin", referers[0]);
        containerResponseContext.getHeaders().add("Access-Control-Allow-Headers", "origin, content-type, accept, authorization, <HERE PUT YOUR DEDICATED HEADERS>);
        containerResponseContext.getHeaders().add("Access-Control-Allow-Credentials", "true");
        containerResponseContext.getHeaders().add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD");
        containerResponseContext.getHeaders().add("Access-Control-Max-Age", "1209600");
}

ด้วยวิธีนี้คุณจะไม่อนุญาตทุกคน

person Geoffrey    schedule 05.06.2017