CORS request made despite error in console - javascript

I'm fiddling around with Google Cloud Storage. I've created a simple Python Flask handler:
#!/usr/bin/env python3
import secrets
import flask
from flask_cors import CORS
from google.cloud import storage
app = flask.Flask(__name__)
CORS(app)
client = storage.Client()
bucket = client.get_bucket('<my-bucket>')
#app.route('/')
def get_upload_urls():
blob = bucket.blob('00000' + secrets.token_hex())
return flask.jsonify({
'url': blob.create_resumable_upload_session(),
})
if __name__ == '__main__':
app.run('0.0.0.0', 9999)
This is accompanied by a really simple web frontend:
index.html:
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="user-scalable=no,initial-scale=1,maximum-scale=1,minimum-scale=1,width=device-width">
<title>Test</title>
</head>
<body>
<input id="input" type="file" />
<button id="button">Upload</button>
<script src="index.js"></script>
</body>
</html>
index.js:
const input = document.getElementById('input')
const button = document.getElementById('button')
button.addEventListener('click', async () => {
const [ body ] = input.files
const response = await fetch('http://localhost:9999')
const { url } = await response.json()
await fetch(url, {
method: 'PUT',
body,
})
})
This frontend allows me to pick a file, and upload it to Google Cloud Storage using a resumable upload session created by the Python backend.
The problem with this is that it actually works. I'd expect the PUT request to fail, but it doesn't.
When a file has been selected and the upload button is pressed, the following errors are logged to the console:
index.html:1 Failed to load
https://www.googleapis.com/upload/storage/v1/b//o?uploadType=resumable&upload_id=:
No 'Access-Control-Allow-Origin' header is present on the requested
resource. Origin 'http://localhost:3333' is therefore not allowed
access. If an opaque response serves your needs, set the request's
mode to 'no-cors' to fetch the resource with CORS disabled.
index.js:13 Uncaught (in promise) TypeError: Failed to fetch
async function (async)
button.addEventListener # index.js:5
However, the PUT request was made succesfully and the file shows up in the Google Cloud Storage. I can download it and it appears to be totally fine.
Why doesn't the PUT request fail despite the CORS error in the console?
Edit:
I'm just looking for an explanation, not for a workaround — I'm going to configure CORS properly anyway. I would just like to know why the request doesn't fail, and why fetch does reject.

#sideshowbarker was right, I had the same issue. CORS needs to be set also in PUT response in addition to OPTIONS preflight request. Then fetch will succeed (even though upload worked before).

Related

Ethers Provider CORS error with JsonRPCProvider inside of react application

Having an issue where my ethers provider is giving me a cors issue for just read only functions. I am not even creating any transactions or anything. I have tried changing nodes and different rpcs but it doesn't help. You can find an image of the errors I get below.
Heres my provider code which I import to all the function pages and heres an example of a function below that. Very basic stuff.
This is a basic react application that is displaying some information about a Binance smart chain token.
import { ethers } from "ethers";
const provider = new ethers.providers.JsonRpcProvider(
"https://speedy-nodes-nyc.moralis.io/1c2baaae7c0d11120337ddc1/bsc/mainnet"
);
export default provider;
Example function:
export const getReflectionLive = async () => {
try {
const tokenContract = new ethers.Contract(tokenAddress, tokenAbi, provider);
let rate = await getDeadRate();
tokenContract.on("Transfer", async (from, to, value, event2) => {
console.log("New Dead Balance addition", (value / 10 ** 9) * 0.05 * rate);
});
} catch (error) {
console.log(`error --> ${error}`);
}
};
All my Error Codes:
Error Codes
×
Unhandled Rejection (Error): could not detect network (event="noNetwork", code=NETWORK_ERROR, version=providers/5.4.4)
Access to fetch at 'https://speedy-nodes-nyc.moralis.io/1c2baaae7c0d11120337ddc1/bsc/mainnet' from origin 'http://localhost:3000' 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.
POST https://speedy-nodes-nyc.moralis.io/1c2baaae7c0d11120337ddc1/bsc/mainnet net::ERR_FAILED
×
Unhandled Rejection (Error): missing revert data in call exception (error={"reason":"processing response error","code":"SERVER_ERROR","body":"{\"jsonrpc\":\"2.0\",\"id\":52,\"error\":{\"code\":-32000,\"message\":\"missing trie node 264c5265b90a8eb574898445f88321e330c126156794b45cfec08ede5c80f693 (path )\"}}","error":{"code":-32000},"requestBody":"{\"method\":\"eth_call\",\"params\":[{\"to\":\"0xc748673057861a797275cd8a068abb95a902e8de\",\"data\":\"0x70a08231000000000000000000000000000000000000000000000000000000000000dead\"},\"0xbc4921\"],\"id\":52,\"jsonrpc\":\"2.0\"}","requestMethod":"POST","url":"https://bsc-dataseed.binance.org/"}, data="0x", code=CALL_EXCEPTION, version=providers/5.4.4)
Assume you know what you are doing (security!) - and in case you have an Apache server running. You might add the following to your site configuration in Apache:
Header set Access-Control-Allow-Origin "*"
Header set Access-Control-Allow-Methods "DELETE, POST, GET, OPTIONS"
Header set Access-Control-Allow-Headers "Content-Type, Access-Control-Allow-Headers, Authorization, X-Requested-With"
Do not forget to enable Apache's header module.
Background:
Ethers.js requires to have in "cross domain/port/server" operation some access rights in order to work in every supported Browser. This forces that the webserver sends all required and allows everything.

Requests failing when made to service URL, but not to version url

I'm trying to set up a service on Google App Engine, but am having trouble getting XmlHttp to work consistently with it.
After deploying, the website can be accessed from 2 different urls: service-dot-project.appspot and version-dot-service-dot-project.appspot, and for some reason there is inconsistencies between the two.
Heres some demo code that verifyably causes me trouble.
# routes.py
from flask import render_template
from . import app
#app.route("/test", methods=["GET"])
def test():
return render_template("test.html")
#app.route("/api/test", methods=["GET"])
def api_test():
return "It Works!"
# templates/test.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Debug</title>
</head>
<body>
<div id="out"></div>
<button type="button" onclick="run()">
Test the thing.
</button>
<script>
function run() {
let xmlHttp = new XMLHttpRequest();
xmlHttp.onreadystatechange = () => {
if (xmlHttp.readyState === 4 && xmlHttp.status === 200)
document.getElementById("out").innerText = xmlHttp.responseText;
}
xmlHttp.open("GET", "/api/test", true);
xmlHttp.send(null);
}
</script>
</body>
</html>
# service.yaml
runtime: python38
service: name
automatic_scaling:
min_idle_instances: 1
instance_class: F4
entrypoint: gunicorn -b :$PORT main:app
env_variables:
...
When I try and press the button on the version url, it works as intended, and "It Works!" gets printed into the div above the button, but on the service url (without the version specified), the page itself loads, but pressing the button causes the request to hang for a few seconds, before printing this to the console:
GET https://service-dot-project.appspot.com/api/test [HTTP/2 404 Not Found 7912ms]
When testing using a local flask debugging environment, the problem does not occur.
Is there something that Google App Engine does that I should know about that may have caused this issue to happen? Is /api a reserved endpoint? The rest of my endpoints works on the service url, its only the api endpoints that break. My only app.before_request method fails with a 403, not a 404, so this cannot be the cause.
if you go to https://console.cloud.google.com/appengine/versions
and select your service that is having troubles, is there some other version that is receiving the traffic instead of your desired version?
Also, try going to the logs, find the entry for the 404, expand it and see which version is throwing that error, under protoPayload > versionId
It seems that the issue is being caused by one of the other services running on our project.
Our default service is defining in its dispatch.yaml
dispatch:
- url: "/api*"
module: otherservice
Which is intercepting all the requests made to myservice-dot-project and redirecting them to otherservice-dot-project
Why this isn't the case for the version url is probably because there is no version of the default service with the same version number.
The fix is to either change the dispatch url of the default service, or change the url of the new service's API endpoints.

GraphQL not making request to WP API

Thanks in advance!
I'm pulling data from a WP Rest API and when spin up the wordpress site on my local machine with the address http://localhost:8000 and got to the graphqli playground on http://localhost:3000/api/graphql and i enter a query i get the expected results and i can consume the data happily in react but once i change the WP rest API address to http://example.com/cms i get back an error. The only thing that changes is the URL so i'm guessing it has to do with CORS.
Inspecting the browser window there is no CORS errors so i can rule out CORS being an issue. The strange thing is that when i make the api call via postman i get the response i expect, when i type in the endpoint in a browser i get the results i expect when i use the endpoint to resolve the query request i get an error, so i started to look at the headers as thats the only thing i can see that changes between a postman request and a normal browser request. for the local wp installation # localhost:8000 looking at the logs i can see the request being made from postman and the browser and axios(used in the query resolver) on the flipside the wp installation thats live on the web the logs show the request from postman and from the browser to the api endpoint but not from the graphql resolver. how do i fix this issue with the resolver not making the request?
this is my resolver for the query
const resolvers = {
Query: {
pages: (_parent, _args, _context) => {
return axios.get(`${wpURL}/wp-json/wp/v2/pages`)
.then(res => res.data)
.catch(error => {
console.log("Response Status:", error.response.status);
console.log("Response Headers:", error.response.headers);
console.log("Response Data:", error.response.data);
});
}
}
}
graphqlserver:
import {ApolloServer} from 'apollo-server-micro'
import Cors from 'micro-cors'
import {schema} from './schema'
const cors = Cors()
const server = new ApolloServer({schema})
const handler = server.createHandler({path: '/api/graphql'})
export const config = {
api: {
bodyParser: false,
}
}
export default cors(handler)
terminal:
> next dev
ready - started server on http://localhost:3000
event - compiled successfully
event - build page: /api/graphql
wait - compiling...
event - build page: /api/graphql
event - compiled successfully
page:
What am i doing wrong?
i figured it out it looks like if the endpoint graphql is fetching data from is not secured via SSL it wont even bother asking for data

How can I make this api call correctly and get the news from the api using fetch [duplicate]

This question already has answers here:
No 'Access-Control-Allow-Origin' header is present on the requested resource—when trying to get data from a REST API
(26 answers)
Closed 2 years ago.
Note: the api Key is fake for privacy.
const url = 'http://newsapi.org/v2/everything?' +
'q=platformer&' +
'apiKey=3ce15c4d1fd3485cbcf17879bab498db';
async function getNews() {
const response = await fetch(url);
const data = await response.json();
console.log(data);
}
getNews()
The problem is that when I run this javascript code I get this error:
Access to fetch at 'http://newsapi.org/v2/everything?q=platformer&apiKey=3ce15c4d1fd3485cbcf17879bab498db' from origin 'null' has been blocked by CORS policy: 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.
Basically I want to pull news from this newsapi.org and and see the data in the console.
The error message of News API provides a hint:
Requests from the browser are not allowed on the Developer plan, except from localhost
Assuming that you are indeed running the app using a local development server (like this one), pointing your browser to http://localhost:8080/ instead of http://127.0.0.1:8080/ does the trick:
Code sample below (run locally with a webserver):
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<h1>News</h1>
<button id="btn-get">Get News</button>
<div id="news-container"></div>
<script>
const url = `https://newsapi.org/v2/everything?q=bitcoin&apiKey=API_KEY`
const newsContainer = document.getElementById('news-container')
function fetchNews(url) {
return fetch(url)
.then(res => res.json())
}
document.getElementById('btn-get').addEventListener('click', () => {
fetchNews(url)
.then(articles => newsContainer.textContent = JSON.stringify(articles))
})
</script>
</body>
</html>
In short, you can utilize a CORS Proxy.
Your question has already been answered here, which provides a larger CORS Proxy explanation and walkthrough.
There's also an accepted answer for NewsApi.org specifically that's a bit more brief here.
Excerpt:
You need a CORS proxy
const proxyUrl = "https://cors-anywhere.herokuapp.com/"
const qInTitle = "";
const from = "";
const apiKey = "";
const url = `${proxyUrl}https://newsapi.org/v2/everything?qInTitle=${qInTitle}&from=${from}language=en&apiKey=${apiKey}`;
const request = new Request(url);
fetch(request)
.then(response => response.json())
.then((news) => {
console.log(news);
})
.catch(error => {
console.log(error);
});
Also, here's a pretty thorough article if you need to know more about CORS in general:
https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS

How does Laravel add X-XSRF-TOKEN automatically when requesting via axios?

I have a API that uses the same auth middleware. So when I am successfully logged in, I am redirected to a page that gets data from my API from the same app. In my app.blade.php I only have axios added and a simple html and take note, I don't even have a csrf-token meta in my header except from my login page which has #csrf in my form.
Here is my app.blade.php layout
<html lang="en">
<head>
<meta charset="UTF-8">
</head>
<body>
#yield('content')
<script src="{{ asset('js/axios.min.js') }}"></script>
<script>
const http = axios.create({
baseURL: '/api'
});
http.interceptors.request.use((request) => {
console.log('Starting Request', request);
return request;
});
</script>
#stack('scripts')
</body>
</html>
and in one of my pages:
#extends('layouts.app')
#section('content')
<div>
<h1>Hello World</h1>
</div>
#endsection
#push('scripts')
<script>
async function test() {
const { data } = await http('/some-page');
// I'm getting a data even without passing a csrf token?
console.log(data);
}
test();
</script>
#endpush
I'm getting the API data even without passing a csrf/xsrf token which is weird.
When I check my console for logs of outgoing request, this is the output
I mean, where did that came form? I don't even have a csrf token in my templates and also nothing or whatsoever passed to my axios config.
Am I missing something here?
Check the docs on XSRF token:
X-XSRF-TOKEN
Laravel stores the current CSRF token in a XSRF-TOKEN cookie that is
included with each response generated by the framework. You can use
the cookie value to set the X-XSRF-TOKEN request header.
This cookie is primarily sent as a convenience since some JavaScript
frameworks and libraries, like Angular and Axios, automatically place
its value in the X-XSRF-TOKEN header.

Categories

Resources