How to define SharedArrayBuffer in Chrome? - javascript

I am working on React + WASM + FFmpeg app following this tutorial
On Chrome, I got the error Uncaught (in promise) ReferenceError: SharedArrayBuffer is not defined error.
I followed the doc reference, and it says the below, which I don't understand.
Cross-origin isolation overview
You can make a page cross-origin isolated by serving the page with these headers:
Cross-Origin-Embedder-Policy: require-corp
Cross-Origin-Opener-Policy: same-origin
What does serving the pages with these headers mean?
How do I implement that?
I even found Chrome dev's official video, but even that does not explain any implementation detail.
Edit2: The best instruction I can find is here, but even that is too vague for me. What does it mean by setting a header? I'm not requesting anything to begin with.
Edit: My React version is already 17.0.2, so this should have been fixed but I am somehow getting this error as well...
[Deprecation] SharedArrayBuffer will require cross-origin isolation as of M92, around July 2021.

The SharedArrayBuffer serves the purpose of sharing data buffers between your main browsing context and another agent (another web page or a worker).
However, to minimize the possible security vulnerabilities, the specification states that this API can only be operated in a secure context.
In addition to this security prerequisite, it is also necessary for any top-level document to be in a Cross Origin Isolation. This means, the party serving the contents should tell the browser that it should block the loading of cross-origin resources. (A document from domain A trying to get data from Domain B)
This is done by the servers by specifying the following two response eaders when serving the website:
Cross-Origin-Opener-Policy: same-origin
Cross-Origin-Embedder-Policy: require-corp
How to specify them in your debug environment?
You need to set up a standard file server such as Apache. Then you will have to tweak its configuration to serve the above headers with the files.
Quick setup: https://www.wampserver.com/en/
An answer provisioning the header info: https://stackoverflow.com/a/35566100/4185234

Let's start off by saying what serving the pages with these headers means.
If you have ever built an API with Express.js for example, you'll be familiar with this. Essentially, it means that when the user makes a GET request to see the web page, you will have to send some additional information in the form of HTTP headers.
Specifically, the first header prevents your page from loading any cross-origin resources that don't explicitly grant permission. The second one means that you can't share a browsing context group with any cross-origin documents. Both of these are used as safety measures to prevent cross-origin attacks. Even though you may not be requesting anything, you have to apply them.
Now onto your problem, I would recommend installing the Chrome extension CORS. I don't know exactly how it works, but I have used it in the past and it will be a temporary solution. I skimmed through the tutorial you're following and I didn't see a server setup (as in Express.js/Node's http for instance). If you had any of these you could pass the headers as arguments to the servers.
To check if the CORS settings are working as intended, add the following code to your app:
if (crossOriginIsolated) {
// Works
}

I ran into this recently and found your question and the answers above
What does serving the pages with these headers mean?
It means configuring the server serving your pages to include those headers. How you configure a server depends on the software you're using, Apache, Nginx, Caddy, or if you're using one of the 1000s of others or writing your own.
I've written 2 (or more correctly, I've used a library to write 2) and I added the option to include those headers. Both are open source so you can look inside if you want to see how they work.
If you prefer a UI then there's this one. If you prefer the command line then install node.js and then you can use this one

Here's a static server example for node.js
var http = require("http");
var fs = require("fs");
var path = require("path");
http
.createServer(function (request, response) {
console.log("request starting...");
response.setHeader("Cross-Origin-Opener-Policy", "same-origin");
response.setHeader("Cross-Origin-Embedder-Policy", "require-corp");
var filePath = "." + request.url;
if (filePath == "./") filePath = "./index.html";
var extname = path.extname(filePath);
var contentType = "text/html";
switch (extname) {
case ".js":
contentType = "text/javascript";
break;
case ".css":
contentType = "text/css";
break;
case ".json":
contentType = "application/json";
break;
case ".png":
contentType = "image/png";
break;
case ".jpg":
contentType = "image/jpg";
break;
case ".wav":
contentType = "audio/wav";
break;
}
fs.readFile(filePath, function (error, content) {
if (error) {
if (error.code == "ENOENT") {
fs.readFile("./404.html", function (error, content) {
response.writeHead(200, { "Content-Type": contentType });
response.end(content, "utf-8");
});
} else {
response.writeHead(500);
response.end(
"Sorry, check with the site admin for error: " +
error.code +
" ..\n"
);
response.end();
}
} else {
response.writeHead(200, { "Content-Type": contentType });
response.end(content, "utf-8");
}
});
})
.listen(80);
console.log("Server running at http://127.0.0.1:80/");

Related

How to create a live website thumbnail as preview

I'm trying to create a gallery in React with life previews of many websites (like a portfolio) all the linked websites belong to me as well.
I already try to use iFrame and embed but I didn't have the result I would like, I'm trying to get a miniature website like in here https://codesandbox.io/explore.
Even tho the website show the thumbnails as images if you update your sandbox it will the images will update too.
I try use iFrame and embed but it does not show a small version of the website but the website as a mobile and just the frame size.
Any ideas in how I could generate such images or solve this problem in some other way?
You cant do this on the front end in a webpage. You need to execute something like puppeteer on your backend to screenshot the pages. An example can be found on
https://bitsofco.de/using-a-headless-browser-to-capture-page-screenshots/
As of the the same-origin policy, browsers do not allow you to make request to a different domain, you cannot request a different domain from your web app.
The Cross-Origin Resource Sharing standard works by adding new HTTP headers that let servers describe which origins are permitted to read that information from a web browser.
As of an alternative solution you can setup an express server and use cors package to add permission for sending request to your other site.
If you control both sites, then config Cross-Origin Resource Sharing (CORS) from server settings by adding new HTTP headers like Access-Control-Allow-Origin to be accept requests from your other servers
var express = require('express')
var cors = require('cors')
var app = express()
app.use(cors())
const whitelist = ['http://example1.com', 'http://example2.com']
const corsOptions = {
origin: function (origin, callback) {
if (whitelist.indexOf(origin) !== -1) {
callback(null, true)
} else {
callback(new Error('Not allowed by CORS'))
}
},
}
app.listen(4000, function () {
console.log('CORS-enabled web server listening on port 4000')
})
There is also a library that captures screenshot of the given url and save it to the given outputFilePath, capture-website, you can use.

trying to enable CORS: require is not defined error

Tl;dr: I'm getting a require is not defined error in the Chrome JS console, despite having installed node.js and requrejs.
I am trying to access API keys in an external JSON file using the following code in main.js:
function readTextFile(file, callback) {
var rawFile = new XMLHttpRequest();
rawFile.overrideMimeType("application/json");
rawFile.open("GET", file, true);
rawFile.onreadystatechange = function() {
if (rawFile.readyState === 4 && rawFile.status == "200") {
callback(rawFile.responseText);
}
}
rawFile.send(null);
}
readTextFile("../secrets.json", function(text){
var data = JSON.parse(text);
apiKey = data.api_key;
username = data.username;
});
and since I use an XMLHttpRequest to the API later, which has an http:// scheme, I am looking to use CORS to work around the same-origin policy.
I put these lines at the beginning of main.js:
var cors = require('cors')
var app = express()
app.use(cors());
and my directory structure looks like this:
/project
index.html
secrets.json
/scripts
main.js
require.js
In the JS console on Chrome I get a require is not defined error. Where have I gone wrong?
This code:
var cors = require('cors')
var app = express()
app.use(cors());
Belongs in a node.js server. It is not to be run inside of Chrome. It's purpose is to help you create an http server that can ACCEPT cross origin http requests from a browser.
A browser will only allow a cross origin XMLHttpRequest if the server itself that you are trying to make the request from specifically allows that cross origin request. So, it would be whatever server that supports the URL you are trying to make the XMLHttpRequest to allows cross origin requests (typically by supporting CORS). If the server does not already support your cross origin call, you would have to either modify that server's code or make the request through some sort of proxy that you do have access to that will get the data for you and relay it back to the browser.
Where have I gone wrong?
Well, the require('cors') along with the other two lines of code you show below it are not meant to run in a browser. They run in a node.js environment and would be used to create an http server that you could then connect to from some outside agent (like a browser's web page).
From the browser, you can't do anything to MAKE a server accept cross origin requests if the server isn't already configured to do so. Your only two options are to change the target server or to use a proxy.
require() is NodeJS feature, see the link for more details.
Could You please share the command You start the app?

CORS policy error while calling remote URL in Angular

Try to call remote API Url but, getting Access-Control-Allow-Origin error. I tried many things like following but, nothing works.
proxy.conf.js
const PROXY_CONFIG = [
{
context: [
"/api/planets"
],
target: "https://swapi.co",
secure: false,
changeOrigin: true,
logLevel: "debug",
bypass: function (req, res, proxyOptions) {
req.headers["Access-Control-Allow-Origin"] = "*";
req.headers["X-Forwarded-Host"] = "localhost:8090";
req.headers["X-Forwarded-For"] = "localhost";
req.headers["X-Forwarded-Port"] = "8090";
req.headers["X-Forwarded-Proto"] = "http";
}
}
];
module.exports = PROXY_CONFIG;
Running with ng serve --port 8090 --proxy-config proxy.conf.js
Can't make any changes in server side because I am using third party API.
Try adding plugin like https://chrome.google.com/webstore/detail/allow-cors-access-control/lhobafahddgcelffkeicbaginigeejlf?hl=en in your chrome browser.
Since you cant change the server side config, so this plugin can do the trick. The browser by default blocks CORS
Since You cannot make any changes on remote server. So it can be escaped using Reverse proxy server. I also faced the same issue while calling linkedin services.
a. There is an https://cors-anywhere.herokuapp.com/ you can append this before your url
and it will temporarily resolve CORS issues.
Since in enterprise scenario you can not use herokuapp.com before your application specific names so better to set below proxy server.
b. Second approach is using rever-proxy approach and set up your own server (local or remote ) for reverse proxying.
https://stackoverflow.com/q/29670703/7562674
You can also implement reverse-proxy like implementation using Spring and Jersey.
https://github.com/hhimanshusharma70/cors-escape
As the error says, a header named Access-Control-Allow-Origin must be present in a CORS response.
Since swapi.co responses include the Access-Control-Allow-Origin header for correct CORS requests (can be tested with a simple fetch('https://swapi.co/api/planets/') from your browser's dev console), the issue may be because of your proxy settings.
Try modifying the response in the proxy bypass method:
bypass: function (req, res, proxyOptions) {
...
// Note that this is "res", not "req".
res.headers["Access-Control-Allow-Origin"] = "*";
...
}
You can't! End of story. If the owner of the api has decided not to allow cross origin requests then you can't. If your are not going to host your app on the https://swapi.co domain then you will not be able to use the api directly from Angular and you will need some kind of pass through api call on the server from .NET, Node, PHP, Java etc.

Cross-Origin Read Blocking (CORB)

I have called third party API using Jquery AJAX. I am getting following error in console:
Cross-Origin Read Blocking (CORB) blocked cross-origin response MY URL with MIME type application/json. See https://www.chromestatus.com/feature/5629709824032768 for more details.
I have used following code for Ajax call :
$.ajax({
type: 'GET',
url: My Url,
contentType: 'application/json',
dataType:'jsonp',
responseType:'application/json',
xhrFields: {
withCredentials: false
},
headers: {
'Access-Control-Allow-Credentials' : true,
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'GET',
'Access-Control-Allow-Headers':'application/json',
},
success: function(data) {
console.log(data);
},
error: function(error) {
console.log("FAIL....=================");
}
});
When I checked in Fiddler, I have got the data in response but not in Ajax success method.
Please help me out.
dataType:'jsonp',
You are making a JSONP request, but the server is responding with JSON.
The browser is refusing to try to treat the JSON as JSONP because it would be a security risk. (If the browser did try to treat the JSON as JSONP then it would, at best, fail).
See this question for more details on what JSONP is. Note that is a nasty hack to work around the Same Origin Policy that was used before CORS was available. CORS is a much cleaner, safer, and more powerful solution to the problem.
It looks like you are trying to make a cross-origin request and are throwing everything you can think of at it in one massive pile of conflicting instructions.
You need to understand how the Same Origin policy works.
See this question for an in-depth guide.
Now a few notes about your code:
contentType: 'application/json',
This is ignored when you use JSONP
You are making a GET request. There is no request body to describe the type of.
This will make a cross-origin request non-simple, meaning that as well as basic CORS permissions, you also need to deal with a pre-flight.
Remove that.
dataType:'jsonp',
The server is not responding with JSONP.
Remove this. (You could make the server respond with JSONP instead, but CORS is better).
responseType:'application/json',
This is not an option supported by jQuery.ajax. Remove this.
xhrFields: {
withCredentials: false },
This is the default. Unless you are setting it to true with ajaxSetup, remove this.
headers: {
'Access-Control-Allow-Credentials' : true,
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'GET',
'Access-Control-Allow-Headers':'application/json',
},
These are response headers. They belong on the response, not the request.
This will make a cross-origin request non-simple, meaning that as well as basic CORS permissions, you also need to deal with a pre-flight.
In most cases, the blocked response should not affect the web page's behavior and the CORB error message can be safely ignored. For example, the warning may occur in cases when the body of the blocked response was empty already, or when the response was going to be delivered to a context that can't handle it (e.g., a HTML document such as a 404 error page being delivered to an tag).
https://www.chromium.org/Home/chromium-security/corb-for-developers
I had to clean my browser's cache, I was reading in this link, that, if the request get a empty response, we get this warning error. I was getting some CORS on my request, and so the response of this request got empty, All I had to do was clear the browser's cache, and the CORS got away. I was receiving CORS because the chrome had saved the PORT number on the cache, The server would just accept localhost:3010 and I was doing localhost:3002, because of the cache.
Return response with header 'Access-Control-Allow-Origin:*'
Check below code for the Php server response.
<?php header('Access-Control-Allow-Origin: *');
header('Content-Type: application/json');
echo json_encode($phparray);
You have to add CORS on the server side:
If you are using nodeJS then:
First you need to install cors by using below command :
npm install cors --save
Now add the following code to your app starting file like ( app.js or server.js)
var express = require('express');
var app = express();
var cors = require('cors');
var bodyParser = require('body-parser');
//enables cors
app.use(cors({
'allowedHeaders': ['sessionId', 'Content-Type'],
'exposedHeaders': ['sessionId'],
'origin': '*',
'methods': 'GET,HEAD,PUT,PATCH,POST,DELETE',
'preflightContinue': false
}));
require('./router/index')(app);
It's not clear from the question, but assuming this is something happening on a development or test client, and given that you are already using Fiddler you can have Fiddler respond with an allow response:
Select the problem request in Fiddler
Open the AutoResponder tab
Click Add Rule and edit the rule to:
Method:OPTIONS server url here, e.g. Method:OPTIONS http://localhost
*CORSPreflightAllow
Check Unmatched requests passthrough
Check Enable Rules
A couple notes:
Obviously this is only a solution for development/testing where it isn't possible/practical to modify the API service
Check that any agreements you have with the third-party API provider allow you to do this
As others have noted, this is part of how CORS works, and eventually the header will need to be set on the API server. If you control that server, you can set the headers yourself. In this case since it is a third party service, I can only assume they have some mechanism via which you are able to provide them with the URL of the originating site and they will update their service accordingly to respond with the correct headers.
If you are working on localhost, try this, this one the only extension and method that worked for me (Angular, only javascript, no php)
https://chrome.google.com/webstore/detail/moesif-orign-cors-changer/digfbfaphojjndkpccljibejjbppifbc/related?hl=en
In a Chrome extension, you can use
chrome.webRequest.onHeadersReceived.addListener
to rewrite the server response headers. You can either replace an existing header or add an additional header. This is the header you want:
Access-Control-Allow-Origin: *
https://developers.chrome.com/extensions/webRequest#event-onHeadersReceived
I was stuck on CORB issues, and this fixed it for me.
have you tried changing the dataType in your ajax request from jsonp to json? that fixed it in my case.
There is an edge case worth mentioning in this context: Chrome (some versions, at least) checks CORS preflights using the algorithm set up for CORB. IMO, this is a bit silly because preflights don't seem to affect the CORB threat model, and CORB seems designed to be orthogonal to CORS. Also, the body of a CORS preflight is not accessible, so there is no negative consequence just an irritating warning.
Anyway, check that your CORS preflight responses (OPTIONS method responses) don't have a body (204). An empty 200 with content type application/octet-stream and length zero worked well here too.
You can confirm if this is the case you are hitting by counting CORB warnings vs. OPTIONS responses with a message body.
It seems that this warning occured when sending an empty response with a 200.
This configuration in my .htaccess display the warning on Chrome:
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST,GET,HEAD,OPTIONS,PUT,DELETE"
Header always set Access-Control-Allow-Headers "Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers, Authorization"
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]
But changing the last line to
RewriteRule .* / [R=204,L]
resolve the issue!
I have a similar problem. My case is because the contentType of server response is application/json, rather than text/javascript.
So, I solve it from my server (spring mvc):
// http://127.0.0.1:8080/jsonp/test?callback=json_123456
#GetMapping(value = "/test")
public void testJsonp(HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse,
#RequestParam(value = "callback", required = false) String callback) throws IOException {
JSONObject json = new JSONObject();
json.put("a", 1);
json.put("b", "test");
String dataString = json.toJSONString();
if (StringUtils.isBlank(callback)) {
httpServletResponse.setContentType("application/json; charset=UTF-8");
httpServletResponse.getWriter().print(dataString);
} else {
// important: contentType must be text/javascript
httpServletResponse.setContentType("text/javascript; charset=UTF-8");
dataString = callback + "(" + dataString + ")";
httpServletResponse.getWriter().print(dataString);
}
}
Response headers are generally set on the server. Set 'Access-Control-Allow-Headers' to 'Content-Type' on server side
I had the same problem with my Chrome extension. When I tried to add to my manifest "content_scripts" option this part:
//{
// "matches": [ "<all_urls>" ],
// "css": [ "myStyles.css" ],
// "js": [ "test.js" ]
//}
And I remove the other part from my manifest "permissons":
"https://*/"
Only when I delete it CORB on one of my XHR reqest disappare.
Worst of all that there are few XHR reqest in my code and only one of them start to get CORB error (why CORB do not appare on other XHR I do not know; why manifest changes coused this error I do not know). That's why I inspected the entire code again and again by few hours and lost a lot of time.
I encountered this problem because the format of the jsonp response from the server is wrong. The incorrect response is as follows.
callback(["apple", "peach"])
The problem is, the object inside callback should be a correct json object, instead of a json array. So I modified some server code and changed its format:
callback({"fruit": ["apple", "peach"]})
The browser happily accepted the response after the modification.
Try to install "Moesif CORS" extension if you are facing issue in google chrome. As it is cross origin request, so chrome is not accepting a response even when the response status code is 200

Issue with reading Response headers

I am trying to build a chrome extension for which i need to ping to different machines.The code which i tried with is able to read the response headers for a https site but not for http.I am new to Javascripting. Any help would be great.I understand it is a CORS issue and tried setting the headers in the client code.many forums mention it setting al the server side but where can I do in this case? Please find the code below and the plugin UI and response returned from https site in the snapshot.
Code--
url="https://www.icicibank.com/";
//url = "www.rediff.com/";
ping = new XMLHttpRequest();
ping.open("get", url,true);
//ping.setRequestHeader("Access-Control-Allow-Origin","*");
// ping.setRequestHeader("Access-Control-Allow-Credentials", "true");
ping.send(null)
ping.onreadystatechange=function() {
if (ping.readyState==4) {
alert(ping.getAllResponseHeaders());
//alertify.alert(ping.getAllResponseHeaders());
}
}
Thanks
CORS is indeed part of the server response, not the request. So you cannot "set" it on your side.
However, extensions are allowed to bypass CORS restrictions and make cross-origin requests. But for that you need to list domains you're going to connect to in manifest permissions. The user will be warned, at install time, that you'll interact with those domains.
For example, to allow requests to http://example.com and https://example.com domains regardless of CORS, you need to include in the manifest:
"permissions" : [
"*://example.com/"
],
If you can't say which sites you'll need to connect to in advance, you'll either need permissions for all urls (special permission, literally, "<all_urls>") or use Optional Permissions to request that at runtime.

Categories