React native fetch data - javascript

I have a problem with fetch data. My friend creates Rest Api.
There is my fun:
const AnyCors = `https://cors-anywhere.herokuapp.com/`;
const urlAllBus = `http://207.185.72.111:15430/stops?size=15`;
fetchBusStop = () => {
return new Promise((resolve, rejects) => {
fetch(AnyCors+urlAllBus)
.then((result) => {
if (!result.ok) throw result.json();
return result.json();
})
.then((result) => {
console.log(result);
resolve(result);
})
.catch((error) =>
error.then((body) => {
console.log('Bad', body);
rejects(body);
}),
);
});
};
I create an app with react-native. When I use only urlAllBus my virtual machine work fine. The problem is with a physical machine. When I try using my fun with urlAllbus in chrome I get a problem with CORS so I used AnyCors+urlAllBus and everything works fine. But in the virtual and physical machine there solutions not work. I don't know what I should do

You friend's API should accept CORS by adding a Access-Control-Allow-Origin: * header to its responses to allow any website to access it. They can also limit access to a specific site by setting the header to the base URL of such site, like Access-Control-Allow-Origin: http://example.com.
If the API is express-based, I hightly recommend the cors package for the job, as it makes it a single-line change.
Otherwise, tell them to give this MDN page a read for more information about CORS :)

Related

Make local storage that can't be changed

Is there a way to make local-storage (or some other client side storage) impossible for users to change in the dev tools? Say I have a feature in which the user needs to pay money for or complete a challenge to get, and the program wants to check if the user has that feature. How can I stop people from going into the developer tools and manually adding that feature?
The closest thing to what ypu decribe is a JWT.
The token would contain this config and is signed with encryption, so the user won't be able to alter the config value without corrupting the token.
However, of course if you are doing this logic on the client side they could always find other ways of manipulating this. E.g. intercepting your JavaScript and altering it never check permissions at all.
You will always be better off handling security server side, then you could choose to only serve these scripts to people who have paid for them.
You can use indexedDB, Which use can't modify by themself.
Code for Angular 9. I have use localforage.
import * as localforage from 'localforage';
// store particular key details
setDataInIndexedDB(key, value) {
return localforage.setItem(key, JSON.stringify(value))
.then(() => { })
.catch(() => { });
}
// fetch particular key details
async getDataFromIndexedDB(key) {
return new Promise((resolve, reject) => {
localforage.getItem(key)
.then((result: any) => {
resolve(JSON.parse(result));
})
.catch((err) => {
reject(err);
});
});
}
// For Remove Particular Field/Key
removeDataFromIndexedDB(key) {
return new Promise((resolve, reject) => {
localforage.removeItem(key)
.then((result: any) => {
const remove = 'Key Removed';
return resolve(remove);
}).catch((err) => {
return reject(err);
});
});
}
// Database has been entirely deleted.
clearDataFromIndexedDB() {
return localforage.clear();
}
Edit IndexedDB

Detect fetch API request on web page in JavaScript

Background: I am working with the Shopify ScriptTag which allows me to add a JavaScript file on the storefront. All I have is that script file.
Current Behaviour: There is an option, "Buy It Now", which allow customers to checkout directly by skipping Add To Cart. When they click on Buy It Now, Shopify sends a fetch() POST request to checkouts.json to create the checkout.
Problem: I need to detect that this "fetch request happened" in my own JavaScript file.
self.addEventListener('fetch', event => {
console.log("event happened");
});
I have tried Fetch Event API, but it seems to be only working in Service Worker scope.
Is there a possibility to detect this?
Like we can detect XMLHttpRequest by overriding its open method using prototypal inheritance.
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.initiatorType === "fetch") {
console.log('Fetch request detected to', entry.name);
}
}
});
observer.observe({
entryTypes: ["resource"]
});
fetch('https://cors-anywhere.herokuapp.com/')
.then(res => res.text())
.then(text => console.log(text.split('\n')[0]));
Using Performance Observer. Thanks to #guest271314.
Yes, you can overwrite window.fetch with your own function that calls the original window.fetch after (or before) running your own code:
const nativeFetch = window.fetch;
window.fetch = function(...args) {
console.log('detected fetch call');
return nativeFetch.apply(window, args);
}
fetch('https://cors-anywhere.herokuapp.com/')
.then(res => res.text())
.then(text => console.log(text.split('\n')[0]));

How to log the AWS Amplify API.get request to view queryStringParameters on url

I'm not sure how to log / see the actual request that is being made.
I can look at this code below and assume that it's http://myendpoint.com?my/path?param=value, however with more complex code and variables in other places, how can I tell what exactly is getting called via API.get?
The main reason I ask is because I don't think my query parameters are being appended to my request, and I'm hoping to confirm.
const apiName = 'http://myendpoint.com'
const path = '/my/path'
const myInit = {
queryStringParameters: {
param: 'value'
}
}
API.get(apiName, path, myInit)
.then((response) => {
console.log('> > > PLEASE TELL ME HOW TO LOG THE REQUEST < < <')
resolve(response)
},
(err) => {
console.log('err resp', err)
resolve(err)
})
Edit: FYI this is in a REACT NATIVE project, so things like the Chrome Network tab are of no use unfortunately.
Okay, I actually think I figured this out, and it boiled down to two different things:
1. ADDING THE AMPLIFY LOGGER:
I found there is an Amplify logger via:
https://github.com/aws/aws-amplify/blob/master/media/logger_guide.md
So I added:
Amplify.Logger.LOG_LEVEL = 'DEBUG'
and now when I am debugging in VS Code I'm seeing the request URL being logged.
2. REALIZING 'queryStringParameters' ISN'T ACTUALLY SUPPORTED: .
I was looking through the Amplify GitHub repo issues and found out that queryStringParameters isn't actually supported yet, which is fun.
URL to issue: https://github.com/aws/aws-amplify/issues/127 .
So instead I appended all my query parameters onto the path, and that works:
const apiName = 'http://myendpoint.com'
const path = `/my/path?param=${value}`
API.get(apiName, path)
.then((response) => {
resolve(response)
},
(err) => {
console.log('err resp', err)
resolve(err)
})
I am now seeing the request URL logged, and seeing the parameters as a part of the request.

CF Connect to the cloud controller

I use the following lib to connect to the cloud controller
https://github.com/prosociallearnEU/cf-nodejs-client
const endpoint = "https://api.mycompany.com/";
const username = "myuser";
const password = "mypass";
const CloudController = new (require("cf-client")).CloudController(endpoint);
const UsersUAA = new (require("cf-client")).UsersUAA;
const Apps = new (require("cf-client")).Apps(endpoint);
CloudController.getInfo().then((result) => {
UsersUAA.setEndPoint(result.authorization_endpoint);
return UsersUAA.login(username, password);
}).then((result) => {
Apps.setToken(result);
return Apps.getApps();
}).then((result) => {
console.log(result);
}).catch((reason) => {
console.error("Error: " + reason);
});
I try to run it against our API and its not working and Im not getting no error message in the console, what it can be ?
where does the space/org is handled here ? since when I connect from the cli it ask me to which space/org I want to connect...
Im able to login via the CLI, just from the code I cant, any idea what is missing here?
The issue it when I run it I dont get any error that can help to understand what is the root cause
I cloned the original git repository and modified some methods to support proxy. Please note that I modified just some methods to get the sample code working, but a complete refactor of the package is needed.
Basically what you have to do is to add a proxy parameter before calling the request method (this is done throughout the package, so several modifications are needed), for example this is for one of the methods in the Organization.js file:
getSummary (guid) {
const url = `${this.API_URL}/v2/organizations/${guid}/summary`;
const proxy = `${this.API_PROXY}`;
const options = {
method: "GET",
url: url,
proxy: proxy,
headers: {
Authorization: `${this.UAA_TOKEN.token_type} ${this.UAA_TOKEN.access_token}`
}
};
return this.REST.request(options, this.HttpStatus.OK, true);
}
You can find my changes in the git repository below:
https://github.com/adasilva70/cf-nodejs-client.git
I have also created a new sample below. This sample lists all organizations for a user, gets the first organization returned and lists its spaces. You can modify the code to provide a similar functionality that cf login provides (allow you to select an organization then a space).
const endpoint = "https://api.mycompany.com/";
const username = "youruser";
const password = "yourpassword";
const proxy = "http://proxy.mycompany.com:8080";
const CloudController = new (require("cf-nodejs-client")).CloudController(endpoint, proxy);
const UsersUAA = new (require("cf-nodejs-client")).UsersUAA;
const Apps = new (require("cf-nodejs-client")).Apps(endpoint, proxy);
const Orgs = new (require("cf-nodejs-client")).Organizations(endpoint, proxy);
CloudController.getInfo().then((result) => {
console.log(result);
UsersUAA.setEndPoint(result.authorization_endpoint, proxy);
return UsersUAA.login(username, password);
}).then((result) => {
//Apps.setToken(result);
//return Apps.getApps();
Orgs.setToken(result);
return Orgs.getOrganizations();
}).then((result) => {
console.log(result);
org_guid = result.resources[1].metadata.guid;
return Orgs.getSummary(org_guid);
}).then((result) => {
console.log(result);
}).catch((reason) => {
console.error("Error: " + reason);
});
I have done just minor tests to make sure the sample works, so use carefully. Also, the changes will only work for a case where proxy is needed now.
The first thing that strikes me on the library's github site is the warning:
Note: This package is not ready for a production App yet.
It also seems that the project is not being maintained as there are a number of tickets ooened that are quite a few months old that don't have a response.
Anyway, to figure out why the library is not working and producing no error message, I would check out the library source code and add some console logging statements, probably starting with the HttpUtils. For example:
requestWithDefaults(options, function (error, response, body) {
console.log("requestWithDefaults error: ", error)
console.log("requestWithDefaults response: ", response)
console.log("requestWithDefaults body: ", body)
...
}
Alternatively, you could try debugging the code by adding breakpoints to the requestWithDefaults and other key places in the library, using the nodejs debugger.
You could also try debugging the network calls similar to this how to monitor the network on node.js similar to chrome/firefox developer tools?
To understand how to use the library, I would take a look into the tests folder and look for a test that is similar to your use case. There are a reasonable amount if tests that look useful in the test/lib/model/cloudcontroller folder.
As for the question about spaces, I have found an example where you can pass in a space guid to return apps for that space guid.
CloudFoundrySpaces.getSpaceApps(space_guid, filter).then( ... )
I'm assuming the call you are using App.getApps() will return Apps for all spaces/organizations.

Can't set Cookies in browser even though header is present

I was working on adding cookies to my project, full source here, but I ran into an issue where I can't set the cookies properly. I made a new api route that just creates a cookie and sends an object to the client.
server/routes/todo.routes.js
router.get('/todos', (req, res) => {
res.cookie('mycookie', 'a_value')
return res.send([{id:'1',isCompleted:false,text:'something'}])
})
If I call this api route directly, the browser renders the object and the cookie is set. The problem is when I call this api via AJAX from a rendered page, I still get the same response, but cookies aren't set. NOTE: I export the router and do app.use('/api', exported_object_here), so the URL is /api/todos.
shared/actions/todo.actions.js
export const getTodos = () => {
return (dispatch) => {
return fetch('/api/todos')
.then(response => response.json())
.then(todo => dispatch(_receiveTodos(todo)))
.catch(err => dispatch(_errorHandler(err)));
}
};
I have no idea why the browser would act differently in that situation, especially with something so simple. Do you all have any clue what could cause this?
You need to set withCredentials on your XHR request (https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/withCredentials)

Categories

Resources