When you send an HTTP request with a different domain than your page’s domain (or IP address + port number), a CORS error may occur. A CORS error means that the API server rejected your request. To access other domain API from your web page, the backend server you requested must set some CORS headers in the HTTP response to allow CORS requests. Below are some errors caused by incorrectly set HTTP response headers for CORS requests.
Error: No ‘Access-Control-Allow-Origin’ header is present
Error information in web browser console
Access to XMLHttpRequest at 'http://localhost:8081/api' from origin 'http://localhost' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. GET http://localhost:8081/api net::ERR_FAILED 302
Solutions
First, check that the URL, Method, and Content-Type you requested are correct.
Make sure the server API is up and running.
Enable CORS requests for your server API. Add Access-Control-Allow-Origin in HTTP response header.
Access-Control-Allow-Origin: * or Access-Control-Allow-Origin: http://your_page_domain
For example, in Java web projects.
response.setHeader("Access-Control-Allow-Origin", "*"); // or response.setHeader("Access-Control-Allow-Origin", "http://localhost");
Reasons
The API is not shared with other origins. You need to update the API CORS policy by set Access-Control-Allow-Origin in response headers.
Error: Method xxx is not allowed
Error information in web browser console
Access to XMLHttpRequest at 'http://localhost:8081/api/delete' from origin 'http://localhost' has been blocked by CORS policy: Method DELETE is not allowed by Access-Control-Allow-Methods in preflight response.
Solutions
Add Access-Control-Allow-Methods: {method_name_in_error_message} in HTTP response header. Note that method names must be capitalized.
The default allowed HTTP methods for CORS are GET, POST, and HEAD. For other HTTP methods like DELETE or PUT, you need to add it to HTTP response header Access-Control-Allow-Methods.
Error: Request header field xxx is not allowed
Error information in web browser console
Access to XMLHttpRequest at 'http://localhost:8081/api/delete' from origin 'http://localhost' has been blocked by CORS policy: Request header field my-header1 is not allowed by Access-Control-Allow-Headers in preflight response.
Access to XMLHttpRequest at 'http://localhost:8081/api/get?name=Jack' from origin 'http://localhost' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
Solutions
Add Access-Control-Allow-Headers: {header_field_name_in_error_message} in HTTP response header.
The default allowed HTTP headers for CORS requests are:
Accept
Accept-Language
Content-Language
Content-Type (value only be application/x-www-form-urlencoded, multipart/form-data, or text/plain)
Range
For other HTTP headers, you need to add them to HTTP response header Access-Control-Allow-Headers.
Error: The value of the ‘Access-Control-Allow-Origin’ header in the response must not be the wildcard ‘*’
Error information in web browser console
Access to XMLHttpRequest at 'http://localhost:8081/api/get' from origin 'http://localhost' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Solutions
Set the value of Access-Control-Allow-Origin to your page domain instead of * in HTTP response header. And set the value of Access-Control-Allow-Credentials to true.
Error: The value of the ‘Access-Control-Allow-Credentials’ header in the response is ‘’ which must be ‘true’
Error information in web browser console
Access to XMLHttpRequest at 'http://localhost:8081/api/get' from origin 'http://localhost' has been blocked by CORS policy: The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
Solutions
Add Access-Control-Allow-Credentials: true in HTTP response header.
When the request’s credentials flag is true, the HTTP response header Access-Control-Allow-Credentials should be true.
Conclusion
There are two scenarios for setting CORS headers. The headers you need to set in each case are given below.
1. No credentials
response.setHeader("Access-Control-Allow-Origin", "*"); // You can also set a specific host. response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, PATCH"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, {my-custome-header}"); response.setHeader("Access-Control-Max-Age", "86400");
2. With credentials
response.setHeader("Access-Control-Allow-Origin", "{your_host}"); // If you use a web framework, it may support setting allow-origin patterns. For example, http://localhost:[*], http://192.168.0.*:[*]. response.setHeader("Access-Control-Allow-Credentials", "true"); response.setHeader("Access-Control-Allow-Methods", "POST, GET, PATCH, DELETE, PUT, PATCH"); response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, {my-custome-header}"); response.setHeader("Access-Control-Max-Age", "86400");
the order to get future results is the tasks order. If the later task executes faster than the earlier task, you still need to wait for the earlier task to complete.
new Random().nextInt(min, max+1) return [min, max]
// Java 8 intsize=1, min = 0, max = 10; ThreadLocalRandomrandom= ThreadLocalRandom.current(); intrandomNumber= random.ints(size, min, max + 1).findFirst().getAsInt();
intsize=5, min = 0, max = 10; ThreadLocalRandomrandom= ThreadLocalRandom.current(); int[] randomNumbers = random.ints(size, min, max + 1).toArray();
intsize=5, min = 0, max = 10; Randomrandom=newRandom(); int[] randomNumbers = random.ints(size, min, max + 1).toArray();
// Java 1.7 or later intmin=0, max = 10; ThreadLocalRandomrandom= ThreadLocalRandom.current(); intrandomNum= random.nextInt(min, max + 1);
// Before Java 1.7 intmin=0, max = 10; Randomrandom=newRandom(); intrandomNum= random.nextInt((max - min) + 1) + min;
Math.random() return [0, 1)
Random.nextInt(n) is more efficient than Math.random() * n
Math.random() uses Random.nextDouble() internally. Random.nextDouble() uses Random.next() twice to generate a double that has approximately uniformly distributed bits in its mantissa, so it is uniformly distributed in the range 0 to 1-(2^-53).
Random.nextInt(n) uses Random.next() less than twice on average- it uses it once, and if the value obtained is above the highest multiple of n below MAX_INT it tries again, otherwise is returns the value modulo n (this prevents the values above the highest multiple of n below MAX_INT skewing the distribution), so returning a value which is uniformly distributed in the range 0 to n-1.
matches() - Checks if the regexp matches the complete string.
Stringsource="hello there, I am a Java developer. She is a Web developer."; Patternpattern= Pattern.compile("a (.*?) developer"); Matchermatcher= pattern.matcher(source); System.out.println(matcher.matches()); // false
Stringsource="hello there, I am a Java developer. She is a Web developer."; Patternpattern= Pattern.compile("a (.*?) developer", Pattern.CASE_INSENSITIVE); Matchermatcher= pattern.matcher(source); // find all match strings while (matcher.find()) { System.out.println(matcher.group()); // a Java developer, a Web developer for (inti=1; i < matcher.groupCount(); i++) { System.out.println(matcher.group(i)); // Java, Web } } // reset matcher for reuse matcher.reset(); // only find once if (matcher.find()) { System.out.println(matcher.group()); // a Java developer System.out.println(matcher.group(1)); // Java }
Replace group string
Stringsource="hello there, I am a Java developer. She is a Web developer."; Stringregex="a (.*?) developer"; intgroupToReplace=1; Stringreplacement="Good"; Matchermatcher= Pattern.compile(regex).matcher(source); StringBuilderresult=newStringBuilder(source); intadjust=0; while (matcher.find()) { intstart= matcher.start(groupToReplace); intend= matcher.end(groupToReplace); result.replace(start + adjust, end + adjust, replacement); adjust += replacement.length() - (end - start); } System.out.println(result); //hello there, I am a Good developer. She is a Good developer.
Notice: To avoid a circular dependency between submodules. A circular dependency occurs when a module A depends on another module B, and the module B depends on module A.
Testing in Spring Boot Multi-Modules Maven Project
Gotenberg-Webhook-Url - the callback to use - required
Gotenberg-Webhook-Error-Url - the callback to use if error - required
Gotenberg-Webhook-Method - the HTTP method to use (POST, PATCH, or PUT - default POST).
Gotenberg-Webhook-Error-Method - the HTTP method to use if error (POST, PATCH, or PUT - default POST).
Gotenberg-Webhook-Extra-Http-Headers - the extra HTTP headers to send to both URLs (JSON format).
Common Errors
Error: file name is too long
{"level":"error","ts":1649232587.172472,"logger":"api","msg":"create request context: copy to disk: create local file: open /tmp/9e10e36d-c5a9-4623-9fac-92db4a0d0982/xxx.doc: file name too long","trace":"de0b5ce2-5a99-406e-a61d-4abb65ef0294","remote_ip":"xxx.xxx.xxx.xxx","host":"xxx.xxx.xxx.xxx:3000","uri":"/forms/libreoffice/convert","method":"POST","path":"/forms/libreoffice/convert","referer":"","user_agent":"okhttp/4.9.3","status":500,"latency":13161094736,"latency_human":"13.161094736s","bytes_in":6983097,"bytes_out":21}
Solutions
Decreasing your file name length.
Error: file name contains UTF-8 characters
{"level":"error","ts":1649234692.9638329,"logger":"api","msg":"convert to PDF: unoconv PDF: unix process error: wait for unix process: exit status 6","trace":"28d9a196-10e5-4c7d-af6a-178494f49cd1","remote_ip":"xxx.xxx.xxx.xxx","host":"xxx.xxx.xxx.xxx:3000","uri":"/forms/libreoffice/convert","method":"POST","path":"/forms/libreoffice/convert","referer":"","user_agent":"okhttp/4.9.3","status":500,"latency":130617774,"latency_human":"130.617774ms","bytes_in":11559,"bytes_out":21}
Solutions
Encoding filename by URLEncoder.encode(fileName, "UTF-8").