B4J Question Preflight CORS issue

xulihang

Active Member
Licensed User
Longtime User
I started a server with SSL support with the domain pointing to 127.0.0.1.

I've also added the header in the handler:

B4X:
resp.SetHeader("Access-Control-Allow-Origin","*")
resp.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, HEAD, DELETE, PUT")
resp.setHeader("Access-Control-Max-Age", "3600")
resp.setHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, api_key")

But I am still getting the preflight CORS issue on Chrome.

B4X:
Access to fetch at 'https://local.basiccat.org:51043/' from origin 'https://ac.qq.com' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.

Are there any solutions?
 
Solution
Just to check, but you have a FILTER (not handler) that does something like this, right?

B4X:
resp.ContentType = "application/json"
resp.SetHeader("Access-Control-Allow-Origin","*")
resp.SetHeader("Access-Control-Allow-Methods" ,"GET, POST, UPDATE, DELETE, OPTIONS")
resp.SetHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, api_key") '<-------- change to whatever you need
If req.Method = "OPTIONS" Then
       Return True
End If
resp.SetHeader("X-Frame-Options", "DENY")
resp.SetHeader("X-XSS-Protection", "1;mode=block")
resp.SetHeader("Strict-Transport-Security"...

xulihang

Active Member
Licensed User
Longtime User
Don't confuse SSL and CORS. You should configure CORS before server starts.
I've configured CORS according to this as well: https://www.b4x.com/android/forum/threads/banano-b4j-the-dreaded-cors-exception-solved.141890/

Curl result:

B4X:
curl https://local.basiccat.org:51043/translate                                                                                           
StatusCode        : 200
StatusDescription : OK
Content           : no imagetrans is connected
RawContent        : HTTP/1.1 200 OK
                    Access-Control-Allow-Origin: *
                    Access-Control-Allow-Methods: POST, GET, OPTIONS, DELETE, PUT
                    Access-Control-Max-Age: 3600
                    Access-Control-Allow-Headers: Access-Control-Allow-Headers...
Forms             : {}
Headers           : {[Access-Control-Allow-Origin, *], [Access-Control-Allow-Methods, POST, GET, OPTIONS, DELETE, PUT],
                    [Access-Control-Max-Age, 3600], [Access-Control-Allow-Headers, Access-Control-Allow-Headers, Origin, Accept,
                    X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization,
                    api_key]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 26
 
Upvote 0

xulihang

Active Member
Licensed User
Longtime User
After changing it to the following:

B4X:
ConfigureCORS("/*", "*", "GET,POST,HEAD,OPTIONS", "X-Requested-With,Content-Type,Accept,Origin")

I got another error:

B4X:
Access to fetch at 'https://local.basiccat.org:51043/translate' from origin 'https://www.basiccat.org' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Private-Network' header was present in the preflight response for this private network request targeting the `local` address space.
 
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Upvote 0

alwaysbusy

Expert
Licensed User
Longtime User
Just to check, but you have a FILTER (not handler) that does something like this, right?

B4X:
resp.ContentType = "application/json"
resp.SetHeader("Access-Control-Allow-Origin","*")
resp.SetHeader("Access-Control-Allow-Methods" ,"GET, POST, UPDATE, DELETE, OPTIONS")
resp.SetHeader("Access-Control-Allow-Headers", "Access-Control-Allow-Headers, Origin, Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization, api_key") '<-------- change to whatever you need
If req.Method = "OPTIONS" Then
       Return True
End If
resp.SetHeader("X-Frame-Options", "DENY")
resp.SetHeader("X-XSS-Protection", "1;mode=block")
resp.SetHeader("Strict-Transport-Security", "max-age=31536000;includeSubDomains;preload")
resp.SetHeader("X-Content-Type-Options", "nosniff")
resp.SetHeader("Referrer-Policy", "no-referrer-when-downgrade")
resp.SetHeader("Content-Security-Policy", "script-src https://api.yourdomain.com") ' <-------------------- change to what it is for you
resp.SetHeader("Feature-Policy", "microphone 'none'")
 
Upvote 1
Solution

xulihang

Active Member
Licensed User
Longtime User
'Access-Control-Allow-Private-Network' header is not yet supported by Jetty: https://github.com/eclipse/jetty.project/issues/7642

I managed to make it work using a filter.

B4X:
'Filter class
Sub Class_Globals
   
End Sub

Public Sub Initialize
   
End Sub

'Return True to allow the request to proceed.
Public Sub Filter(req As ServletRequest, resp As ServletResponse) As Boolean
    resp.SetHeader("Access-Control-Allow-Private-Network","true")
    Return False
End Sub
 
Upvote 0
Top