If you request with cookie, you need to add another header Access-Control-Allow-Credentials: true to the HTTP response, and the value of Access-Control-Allow-Origin cannot be *.
Optional HTTP response headers for CORS requests:
Access-Control-Max-Age: 86400: tell the browser to cache the preflight response.
Note
The wildcard * is not supported for the Access-Control-Allow-Headers value.
if the value of Access-Control-Allow-Credentials is true, the value of Access-Control-Allow-Origin cannot be *. The Access-Control-Allow-Credentials: true means request with the cookie.
Preflight requests
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method, Access-Control-Request-Headers, and the Origin header. A preflight request is automatically issued by a browser. If the server allows it, then it will respond to the preflight request with an Access-Control-Allow-Methods response header, which lists DELETE or PUT.
Situations that require a preflight request
DELETE and PUT requests.
Requests with custom headers.
The preflight response can be optionally cached for the requests created in the same URL using Access-Control-Max-Age header. Note that if it is cached, it will not issue a preflight request.
An SSL Certificate is essentially an X.509 certificate. X.509 is a standard that defines the structure of the certificate. It defines the data fields that should be included in the SSL certificate. X.509 uses a formal language called Abstract Syntax Notation One (ASN.1) to express the certificate’s data structure.
There are different formats of X.509 certificates such as PEM, DER, PKCS#7 and PKCS#12. PEM and PKCS#7 formats use Base64 ASCII encoding while DER and PKCS#12 use binary encoding. The certificate files have different extensions based on the format and encoding they use.
The X.509 Certificate’s encoding formats and file extensions
Enter PEM pass phrase: Country Name (2 letter code) [AU]: State or Province Name (full name) [Some-State]: Locality Name (eg, city) []: Organization Name (eg, company) [Internet Widgits Pty Ltd]: Organizational Unit Name (eg, section) []: Common Name (e.g. server FQDN or YOUR name) []: Email Address []:
-x509: Output a x509 structure instead of a cert request (Required by some CA’s)
-newkey val: Specify as type:bits. (key algorithm and key size). For example, -newkey rsa:4096
-keyout outfile: File to send the key to (private key)
-out outfile: Output file (certificate)
-days +int: Number of days cert is valid for
-*: Any supported digest. For example, -sha256
Optional options
-nodes: Don’t encrypt the output key.
-subj val: Set or modify request subject. (non-interactive). For example, -subj "/C=XX/ST=StateName/L=CityName/O=CompanyName/OU=CompanySectionName/CN=CommonNameOrHostname"
What is your first and last name? [Unknown]: Herong Yang What is the name of your organizational unit? [Unknown]: Herong Unit What is the name of your organization? [Unknown]: Herong Company What is the name of your City or Locality? [Unknown]: Herong City What is the name of your State or Province? [Unknown]: Herong State What is the two-letter country code for this unit? [Unknown]: CA Is CN=Herong Yang, OU=Herong Unit, O=Herong Company, L=Herong City, ST=Herong State, C=CA correct? [no]: yes
Import
-importcert/-import
// Installing the Self-Signed Certificate on the Client keytool -importcert -alias alias_name -file path_to_certificate_file -keystore truststore_file
// When your index contains semi-structured data or if you don’t have a domain object definition, you can also read the document as raw JSON data. You can use Jackson’s ObjectNode or any JSON representation that can be deserialized by the JSON mapper associated to the ElasticsearchClient. SearchResponse<ObjectNode> response = client.search(s -> s .index("indexName") .from(0) .size(10) .sort(so -> so .field(FieldSort.of(f -> f .field("pub_time") .order(SortOrder.Desc)) ) ) .query(q -> q .bool(b -> b .must(m -> m.term(t -> t .field("name") .value("value") )) ) ) .aggregations("term_aggregation", a -> a .terms(t -> t.field("category")) ), ObjectNode.class );
Elasticsearch no longer recommend using the scroll API for deep pagination. If you need to preserve the index state while paging through more than 10,000 hits, use the search_after parameter with a point in time (PIT).
In order to use scrolling, the initial search request should specify the scroll parameter in the query string, which tells Elasticsearch how long it should keep the “search context” alive (see Keeping the search context alive), eg ?scroll=1m.
The size parameter allows you to configure the maximum number of hits to be returned with each batch of results. Each call to the scroll API returns the next batch of results until there are no more results left to return, ie the hits array is empty.
Developing new features for existing applications. (refer to the corresponding section)
Note: Development of new software product require a lot of time to optimize the user experience and requirements. Therefore, a lot of code modifications are also required.
Developing new features for existing applications
Functional modules
Understand the software requirements.
Design data models and databases.
API design.
Detailed design.
Write unit tests and code.
Test and Fix bugs.
Modify the code due to the modification of the requirements.
Test and Fix bugs.
Data analysis modules
Understand the software requirements.
Write query statements (SQL, Elasticsearch DSL) for data statistics.
Merge query statements to reduce the number of queries.
API design.
Write the code. Define the data query and response objects and finish the code.
Test and Fix bugs.
Scheduled Tasks
Small functions
Understand the software requirements.
Modify data models and databases. (optional)
API design. (optional)
Detailed design.
Write unit tests and code.
Test and Fix bugs.
Modification of system functionality
Understand the software requirements.
Modify data models and databases. (optional)
Modify API. (optional)
Detailed design.
Modify unit tests and code.
Test and Fix bugs.
Performance Optimization
Positioning problem
Try to find the tuning approach
Software product customization (new features and modifications)
Developing new features for existing applications. (refer to the corresponding section)
Modification of system functionality. (refer to the corresponding section)
Maintain systems and miscellaneous
System troubleshooting and fixing errors.
Update data.
Import data.
Export data.
Third party service renewal.
Integrating Code Libraries
Integrating Third-Party Service API or SDK
Common third-party services
Cloud platform
Storage
OSS
AI + Machine Learning
OCR
Media
Intelligent Media Services
Payment. E.g. Alipay.
Mobile Push notifications. E.g. Jiguang, Getui.
Short Message Service (SMS)
Social. E.g. QQ, WeChat, and Dingtalk open platform, Twitter Developer Platform, Slack API.
Sometimes we need to redirect to our other websites without login again. In addition to single sign-on, we can also add a URL parameter to achieve automatic login.
The Process of Login By URL Parameters
The frontend requests the backend API to get the loginSign string for setting the redirect URL parameters. The redirect URL like https://xxx.com/xxx?loginSign=xxx
The backend constructs the loginSign value
Query the redirected website username and password.
Generate a random string.
Get the current timestamp.
Use the RSA public key to encrypt the username, password, timestamp, randomStr.
Return the loginSign value to frontend.
The client user clicks the redirect URL.
When the target website frontend checks that the loginSign parameter appears on the web page URL, it uses this parameter to request login automatically.
The target website backend decrypts the loginSign value, and checks the username and the password. If they are correct returns an access token, otherwise, returns an error code.
Construct the URL Parameter loginSign
Add a newline \n (ASCII 0x0A) to the end of each parameter.
username\n password\n timestamp\n randomStr\n
timestamp: the request timestamp.
Use the RSA public key to encrypt the string {username}\n{password}\n{timestamp}\n{randomStr}\n
Verify the URL Parameter loginSign
Use the RSA private key to decrypt the loginSign value.
Verify the request timestamp if it’s within 60 seconds of the current time.
let result = json != null ? json.name : undefined;
Null Check
if a != null return a, else return default value
// Ternary Operator let result = a != null ? a : defaultValue;
// Logical Operator || // When it's used with non-boolean values, the || operator will return a non-boolean value of one of the specified expression or operands. let result = a || defaultValue;
// Nullish Coalescing Operator ?? let result = a ?? defaultValue;
2
if a != null and b != null return b; else return null;
let result = a != null && a.name != null ? a.name : null;
let result = a && a.name;
Statement
For Loop
for (let i = 0; i < arr.length; ++i) arr.forEach((value, index) => { /* ... */ }) for (let index in arr) for (const value of arr)
Print to console
console.log(obj1 [, obj2, ..., objN]);
console.log(obj) console.log(obj1, obj2) console.log("obj is: ", obj) console.log("obj is: ", obj, ". And my name is ", name) console.log("objects are: ", obj1, obj2) console.log("obj is: " + JSON.parse(JSON.stringify(obj)))
console.log(msg [, subst1, ..., substN]);
%oor%O Outputs a JavaScript object.
%dor%i Outputs an integer.
%s Outputs a string.
%f Outputs a floating-point value.
console.log("obj is %o", obj) console.log("Hello, %s. You've called me %d times.", "Bob", 1);
Object
Merge object fields
let json1 = {"name": "Jack"}; let json2 = { ...json1, age: 18 };
Deep copy
let json = {"name": "Jack"}; let copy = JSON.parse(JSON.stringify(json));
// iterates over all enumerable properties of an object. const jsonObj = {name: "Jack", age: 18} for (const key in jsonObj) { console.log(`${key}: ${jsonObj[key]}`); }
Object.entries() or Object.keys()
// to traverse a Javascript object const jsonObj = {name: "Jack", age: 18} Object.entries(jsonObj).forEach(([key, value]) => { console.log(key, value) });
Object.keys(obj).forEach(function(key) { var value = obj[key]; // ... });
to include non-enumerable properties
Object.getOwnPropertyNames(obj).forEach(function(key) { var value = obj[key]; // ... });
Array
Traversal
for (let i = 0; i < arr.length; ++i) arr.forEach((value, index) => { /* ... */ }) for (let index in arr) for (const value of arr)
forEach: executes a provided function once for each array element. another type of for loop.
NOTE: The forEach loop is another type of for loop in JavaScript. However, forEach() is actually an array method, so it can only be used exclusively with arrays. There is also no way to stop or break a forEach loop. If you need that type of behavior in your loop, you’ll have to use a basic for loop.
// creating regular expression from a string, you have to double-up your backslashes \\. const regex = newRegExp('^\\d{10}$'); const regex = newRegExp('^\\d{10}$', 'g');
/regex/mod
// if you use regex syntax, you need eacape / by \/ const regex = /^\d{10}$/; const regex = /^\d{10}$/g;
API
RegExp
regexp.exec(str) - Returns the first match info array. It likes [matched string, group 1, group 2, ...]. The flag g has no effect.
string.match(regexp) - Returns the first match info array [matched string, group 1, group 2, ...], or return an all matched string array [matched string 1, matched string 2, ...] when it uses the flag g.
let s = "hello1, hello2"; s.match(/hello(\d)/); // return the first match object ['hello1', '1', ...] s.match(/hello(\d)/g); // return all match strings ['hello1', 'hello2']
string.matchAll(regexp) - Returns all match info arrays. The regexp must use the flag g (global search).
let s = "hello1, hello2"; s.matchAll(/hello(\d)/); // Uncaught TypeError: String.prototype.matchAll called with a non-global RegExp argument for (const match of s.matchAll(/hello(\d)/g)) { console.log(match); // the match info array console.log(match[0]); // the matched string console.log(match[1]); // the group 1 of the matched string }
string.replace(regexp, replacement) - Returns a string with the first or all matched string replaced.
let s = "hello1, hello2"; s.replace(/hello(\d)/, 'hey'); // 'hey, hello2' s.replace(/hello(\d)/g, 'hey'); // 'hey, hey'
// replace with group let s = "hello1, hello2"; s.replace(/hello(\d)/, "hi$1"); // 'hi1, hello2' s.replace(/hello(\d)/g, "hi$1"); // 'hi1, hi2' // extract group s.replace(/hello(\d)/g, "$1"); // '1, 2'
string.replaceAll(regexp, replacement) - Returns a string with the all matched string replaced. The regexp must use the flag g (global search).
let s = "hello1, hello2"; s.replaceAll(/hello(\d)/, 'hey'); // Uncaught TypeError: String.prototype.replaceAll called with a non-global RegExp argument s.replaceAll(/hello(\d)/g, 'hey'); // 'hey, hey'
// replace with group. // replaceAll(/xxx/g, '') results are same with replace(/xxx/g, '') s.replaceAll(/hello(\d)/g, "hi$1"); // 'hi1, hi2' s.replaceAll(/hello(\d)/g, "$1"); // '1, 2'
string.search(regexp)
string.split(regexp)
Flags
Flag
Description
Corresponding property
d
Generate indices for substring matches.
hasIndices
g
Global search.
global
i
Case-insensitive search.
ignoreCase
m
Allows ^ and $ to match newline characters.
multiline
s
Allows . to match newline characters.
dotAll
u
“Unicode”; treat a pattern as a sequence of Unicode code points.
unicode
v
An upgrade to the u mode with more Unicode features.
unicodeSets
y
Perform a “sticky” search that matches starting at the current position in the target string.
Make sure to use the u flag at the end of the regex pattern (/.../u) to enable Unicode mode, which is necessary when working with Unicode property escapes.
Single sign-on (SSO) is an authentication method that allows users to sign in using one set of credentials to multiple independent software systems.
Implementations of single sign-on:
Cookie-based
Session-based
Central Authentication Service (CAS)
Cookie-Based SSO
It works by using web based HTTP cookies to transport user credentials from browser to server without from the user. Credentials on the client machine are gathered and encrypted before it being stored in the cookie.
Once the user enters the username and password in any subsystem, the user credentials will be stored in cookie, which is shared by multiple subsystems and automatically sent to the server.
The domain name of each system using cookie-based SSO should be the same or have the same top-level domain name. So user credentials in cookie can be shared between multiple systems.
Advantages
Easy to implement.
Disadvantages
Can’t cross domain.
Session-Based SSO
It works by using web based HTTP cookies to transport user authentication token.
The user token is stored in the client browser and sent to the server as session value. session values and user ID are stored in a cache like Redis shared across subsystems. Each subsystem checks the user from the cache by the token in the HTTP request cookie.
Advantages
Suitable for distributed system applications.
Disadvantages
Can’t cross domain.
Central Authentication Service (CAS)
When the user accesses the application system for the first time, since he has not logged in, he is directed to the authentication system to log in. The authentication system accepts security information such as user name and password, and generates an access token (ticket). The user accesses the application system through the ticket. After receiving the request, the application system will visit the authentication system to check the legitimacy of the ticket. If the check is passed, the user can access the application system resources without logging in again.