Cross-Origin Resource Sharing

This topic explains CORS configuration in PI Web API, as well as instructions for setting up CORS correctly.

Background

Cross-Origin Resource Sharing (CORS) is a World Wide Web Consortium (W3C) specification for secure access to resources hosted in a remote domain. This was introduced to overcome the same-origin policy restriction imposed by most modern web browsers. The same-origin policy limits scripts running in one domain from accessing resources that are hosted in another for security purposes. For example, your application that runs on http://my-internal-site.internal/mygreatapp will not be allowed to make AJAX calls to PI Web API running at https://my-pisystem.internal/piwebapi since https://my-internal-site.internal and https://my-pisystem.internal have different origins.

If you are writing an application against PI Web API with scripts running on the browser (e.g., making an AJAX call in your JavaScript application) and seeing error messages in the browser console related to cross-origin requests, you need to enable CORS in the PI Web API configuration. Otherwise, the browser will prevent your script from accessing resources provided by PI Web API.

With CORS set up, the browser sends the request to the PI Web API server and determines whether the request is allowed based on CORS settings in PI Web API. There are two different ways that the browser can ask for permissions. For simplicity:

For more information about simple vs. complex requests, and about CORS in general, consult the following resources:

Configuration Settings

By default, CORS is disabled in PI Web API. To enable CORS or change CORS settings, choose one of the following actions:

The following CORS configuration items are available in PI Web API:

Troubleshooting Tips

If you are troubleshooting CORS errors, the browser developer tools (usually opened by pressing F12) provide many useful ways to diagnose the error. Remember that the same-origin policy is a browser implementation, so different browsers may exhibit slightly different behaviors.

  1. Look at the error messages in the console. For example,

    • Chrome: XMLHttpRequest cannot load https://my-internal-site.internal/piwebapi. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://my-internal-site.internal' is therefore not allowed access. The response had HTTP status code 400.
    • Firefox: Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at https:// my-internal-site.internal/piwebapi. (Reason: CORS header 'Access-Control-Allow-Origin' missing).
    • Internet Explorer: XMLHttpRequest: Network Error 0x80070005, Access is denied.
  2. The browser usually does not give us details on why the error occurs. Even though the browser specifically says that the CORS header Access-Control-Allow-Origin is missing, this does not mean that the CorsOrigins attribute is the culprit. This is because the server returns a generic response without any CORS headers if any of the CORS check fails.

  3. To identify the misconfigured CORS setting, inspect the request headers.

    • Make sure the value in the Origin header in the request matches with one of the origins specified in the CorsOrigins attribute (unless a wildcard is used).
    • Make sure the value in the Access-Control-Request-Method in the preflight request matches with one of the methods specified in the CorsMethods attribute (unless a wildcard is used).
    • Make sure the values in the Access-Control-Request-Headers in the preflight request match the headers specified in the CorsHeaders attribute (unless a wildcard is used).
    • If your client application is requesting for a specific header (e.g., Location), make sure it is included in the CorsExposedHeaders list.
    • Make sure CorsSupportsCredentials is true if you are using Basic or Kerberos authentication.
  4. Changing configuration setting does not require a restart of the PI Web API service since the service will update its configuration every 15 seconds or so. To make sure the new configuration values are accepted, check the admin logs in the event viewer for any errors and to verify the modified configuration values.

Enabling Operational Intelligence