Antd upload's Dragger component upload occurs across domains - javascript

I use create-react-app to do my front end, and use the Dragger component inside antd's upload. My backend is springboot. My front end sends request data to the backend using fetch, which will cause cross-domain problems. So I added "proxy" in the package.json file of create-react-app: "http://localhost:8080" to proxy my backend, which solves the trouble of cross-domain, but when I use antd official website The uploader's Dragger component always reports an error when uploading.
This is my code for using Antd's Dragger.
import React, { Component } from 'react';
import { Upload, Icon, message } from 'antd';
import './UpVideo.css';
const Dragger = Upload.Dragger;
export default class UpVideo extends Component {
render(){
const props = {
name: 'file',
multiple: false,
headers:{
'Access-Control-Allow-Origin':'*',
'Access-Control-Allow-Methods':'POST',
},
action: 'http://localhost:8080/vidoe/up',
onChange(info) {
// const status = info.file.status;
console.log(info);
// if (status !== 'uploading') {
// console.log(info.file, info.fileList);
// }
// if (status === 'done') {
// message.success(`${info.file.name} file uploaded successfully.`);
// } else if (status === 'error') {
// message.error(`${info.file.name} file upload failed.`);
// }
},
};
return(
<div>
<Dragger {...props}>
<p className="ant-upload-drag-icon">
<Icon type="inbox" />
</p>
<p className="ant-upload-text">点击或者拖动视频文件到这里</p>
</Dragger>,
</div>
)
}
}
This is the picture I gave the error.
I am sorry, I just learned to use StackOverflow. If my description is not clear, please let me know, this question has been annoying me for a long time, thank you.

This error is a security measure of google chrome. It appears when you use a 2 different servers for front and back end. install this library to fix it:
npm install cors
https://www.npmjs.com/package/cors

Related

unable to fetch api using the redux toolkit

I have watched a tutorial to know how redux toolkit work after watching that he uses some online api providing service now when i am using it i need to customize it for my use so i have did change the name and the urls
here is my store.js
import {configureStore} from '#reduxjs/toolkit'
import {setupListeners} from '#reduxjs/toolkit/query'
import { postApi } from './actions/productAction'
export const store = configureStore({
reducer:{
[postApi.reducerPath]:postApi.reducer
},
// middleware:(getDefaultMiddleware)=>getDefaultMiddleware().concat(postApi.middleware),
// middleware is also created for us, which will allow us to take advantage of caching, invalidation, polling, and the other features of RTK Query.
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware().concat(postApi.middleware),
})
setupListeners(store.dispatch)
Here i have the action file which is actually taking the action updating state
import { createApi, fetchBaseQuery } from '#reduxjs/toolkit/query/react'
export const postApi = createApi({
reducerPath:'postApi',//this is unique path which will tell the broweser where it need to store the cookie data
baseQuery: fetchBaseQuery({
baseUrl:'',
}),
endpoints:(builder)=>({
getAllPost: builder.query({
query:()=>({
url:'http://localhost:5000/api/v1/products',
method:'GET'
})
}),
getPostById: builder.query({
query: (id) =>({
url:`posts/${id}`,
method:'GET'
})
})
})
})
export const {useGetAllPostQuery,useGetPostByIdQuery} = postApi
The place where i am calling this function is
import React from 'react'
import {useGetAllPostQuery} from '../../actions/productAction'
// import Card from '../../components/Card';
const HomePage = () => {
console.log(useGetAllPostQuery())
const responseInfo = useGetAllPostQuery()
console.log("the response i am getting is",responseInfo)
return (
<>
<h1>Hello worls</h1>
</>
)
}
export default HomePage
my console where i am getting i dont why this error is coming
the request is rejcted at the same time my post man works on that
The error expanded image
The actual issue is
looks like it is not getting the Url Try adding your base URL like this
export const postApi = createApi({
reducerPath:'postApi',
baseQuery: fetchBaseQuery({
baseUrl:'http://localhost:5000/', //added your base url
}),
endpoints:(builder)=>({
getAllPost: builder.query({
query:()=>({
url:'api/v1/products' // this should take only one argument
})
}),
getPostById: builder.query({
query: (id) =>({
url:`posts/${id}` // this should take only one argument
})
})
})
})
For more Details, you can refer to here rtk query
Bro, I watch that tutorial too, it is old.
Here is the correct way to fetch. Please let me know if this answer help you. And also you auto complete to import. You're not importing from the right place if you follow that tutorial.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
import React from 'react'
import {useGetAllPostQuery} from '../../actions/productAction'
// import Card from '../../components/Card';
const HomePage = () => {
console.log(useGetAllPostQuery())
//You can also desctructure it like this {data:responseInfo}, you must not directly change the value.
const {data} = useGetAllPostQuery()
return (
<>
//Then you check if data exist first because the initial value is empty. you can also check like this <div>{data?.map((my data)=> <>...</>))}</div>
<div>{data && data.map((mydata, i)=> (
//You can tag on what you want to display. if you want to display names, then you can say madata.name
<p key={i}>{mydata}</p>
))}</div>
</>
)
}
export default HomePage
To solve cors errors, try this:
Create vercel.json under the root folder.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
{
"headers": [
{
"source": "/api/(.*)",
"headers": [
{ "key": "Access-Control-Allow-Credentials", "value": "true" },
{ "key": "Access-Control-Allow-Origin", "value": "*" }, // Change this to specific domain for better security
{
"key": "Access-Control-Allow-Methods",
"value": "GET,OPTIONS,PATCH,DELETE,POST,PUT"
},
{
"key": "Access-Control-Allow-Headers",
"value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version"
}
]
}
]
}
Go to /api/index.js file.
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
export default async (req, res) => {
const { method } = req;
// This will allow OPTIONS request
if (method === "OPTIONS") {
return res.status(200).send("ok");
}
};
I was not looking console properly the main issue was that the backend was not allowing me to query the api which is kind strange i have not find this using axios means i not need to use cors to access api using axios but if you are doing it using redux tool kit then you need to use cors
npm install cors
then add these line in your main backend file
const cors = require('cors');
const express = require('express');
const app = express();
app.use(cors());

How can I fix my endpoint not accepting POST requests?

I'm building a custom API, with an endpoint defined as follow:
I have a created a Profiling Controller to handle the logic for this endpoint. My controller directory contains 2 files:
controller.ts
import { Request, Response } from 'express';
import ProfilingService from '../../services/profiling.service';
export class Controller {
enrich_profile(req: Request, res: Response): void {
console.log(req);
ProfilingService.enrich_profile(req).then((r) =>
res
.status(201)
.location(`/api/v1/profile_data/enrich_profile/data${r}`)
.json(r)
);
}
}
export default new Controller();
routes.ts
/* eslint-disable prettier/prettier */
import express from 'express';
import controller from './controller';
export default express.
Router()
.post('/enrich_profile', controller.enrich_profile)
;
However, when I sent a call to the endpoint, I get the following error:
And finally, to allow a full picture, here's the content of profiling.service.ts:
import L from '../../common/logger';
interface Profiling {
data: never;
}
export class ProfilingService {
enrich_profile(data: never): Promise<Profiling> {
console.log(data);
L.info(`update user profile using \'${data}\'`);
const profile_data: Profiling = {
data,
};
return Promise.resolve(profile_data);
}
}
export default new ProfilingService();
The error clearly states that POST to the defined endpoint is not possible, and I'm not sure I understand why.
How can I fix this issue?
I'm not sure what was causing the issue, but after cleaning my npm cache, and deleting node_modules about 100X, the issue finally went away.

display custom error message in a live Player

I have a react code as shown below which renders player on page load. The code goes inside the if block only if the condition is true.
const player = ()=> {
if(condition) {
return (
<ReactJWPlayer
playlist={[props.playlist]}
/>
)
}
}
Problem Statement: For the error code 232011, I am seeing the following error message:
[![enter image description here][1]][1]
This video file cannot be played
(Error Code: 232011)
I am wondering what changes I need to make in the react code above so that I can replace the above error message with the following one in the player.
Video will be available soon
You have to use intl.{lang}.errors object. This object localizes the error messages displayed in the player.
In order to configure intl.{lang}.errors, you will have to use customProps option exposed by react-jw-player to be applied directly to the JW Player instance.
You can stick with en only, or add additional language support depending on your use-case.
import { useRef } from "react";
import ReactJWPlayer from "react-jw-player";
import ReactDOM from "react-dom";
export default function App() {
const jwPlayerRef = useRef();
const myErrorHandler = (err) => {
console.log(err);
// Find the Node where error message is shown
const errorNode = ReactDOM.findDOMNode(
jwPlayerRef.current
).getElementsByClassName("jw-error-text");
// If the error node exists, replace both message and code
if (errorNode && errorNode.length)
errorNode[0].innerText = "Custom Error Message";
};
return (
<div className="App">
<div
className="jw-video-container"
data-mediaid="TAITbudl"
style={{ height: "100%", width: "100%" }}
>
<ReactJWPlayer
ref={jwPlayerRef}
playerId="TAITbudl"
playerScript="https://content.jwplatform.com/libraries/j9BLvpMc.js"
playlist="https://cdn.jwplayer.com/v2/media/123"
onError={myErrorHandler}
onSetupError={myErrorHandler}
customProps={{ // <= Official way to override the error message
intl: {
en: {
errors: {
badConnection:
"This video cannot be played because of a problem with your internet connection.",
cantLoadPlayer: "Sorry, the video player failed to load.",
cantPlayInBrowser:
"The video cannot be played in this browser.",
cantPlayVideo: "This is my custom error Message",
errorCode: "Code - ",
liveStreamDown:
"The live stream is either down or has ended.",
protectedContent:
"There was a problem providing access to protected content.",
technicalError:
"This video cannot be played because of a technical error."
}
}
}
}}
/>
</div>
</div>
);
}
The intl object allows you to add new language translations, [...] - Docs
Note that getElementsByClassName("jw-error-text") is a hack, and if JW Player decided to change the class name, or obfuscate it, this hack will break.

Can you track background geolocation with React Native?

Problem
I'd like to be able to track a users location even when the app is no longer in the foreground (e.g. The user has switch to another app or switched to the home screen and locked their phone).
The use case would be a user tracking a run. They could open the app and press 'start' at the beginning of their run, then switch or minimise the app (press the home button) and lock the screen. At the end of the run they could bring the app into the foreground and press 'stop' and the app would tell them distance travelled on the run.
Question
Is tracking background geolocation possible on both iOS and Android using pure react native?
The react native docs on geolocation (https://facebook.github.io/react-native/docs/geolocation) are not very clear or detailed. The documented linked above eludes to background geolocation on iOS (without being fully clear) but does not mention Android.
Would it be best that I use Expo?
UPDATE 2019 EXPO 33.0.0:
Expo first deprecated it for their SDK 32.0.0 to meet app store guidelines but then reopened it in SDK 33.0.0.
Since, they have made it super easy to be able to implement background location. Use this code snippet that I used to make background geolocation work.
import React from 'react';
import { Text, TouchableOpacity } from 'react-native';
import * as TaskManager from 'expo-task-manager';
import * as Location from 'expo-location';
const LOCATION_TASK_NAME = 'background-location-task';
export default class Component extends React.Component {
onPress = async () => {
await Location.startLocationUpdatesAsync(LOCATION_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
timeInterval: 5000,
});
};
render() {
return (
<TouchableOpacity onPress={this.onPress} style={{marginTop: 100}}>
<Text>Enable background location</Text>
</TouchableOpacity>
);
}
}
TaskManager.defineTask(LOCATION_TASK_NAME, ({ data, error }) => {
if (error) {
alert(error)
// Error occurred - check `error.message` for more details.
return;
}
if (data) {
const { locations } = data;
alert(JSON.stringify(locations); //will show you the location object
//lat is locations[0].coords.latitude & long is locations[0].coords.longitude
// do something with the locations captured in the background, possibly post to your server with axios or fetch API
}
});
The code works like a charm. One thing to note is that you cannot use geolocation in the Expo App. However, you can use it in your standalone build. Consequently, if you want to use background geolocation you have to use this code and then do expo build:ios and upload to the appstore in order to be able to get a users background location.
Additionally, note that you must include
"UIBackgroundModes":[
"location",
"fetch"
]
In the info.plist section of your app.json file.
The Expo Team release a new feature in SDK 32 that allow you tracking in background the location.
https://expo.canny.io/feature-requests/p/background-location-tracking
Yes is possible, but not using Expo, there are two modules that I've seen:
This is a comercial one, you have to buy a license https://github.com/transistorsoft/react-native-background-geolocation
And this https://github.com/mauron85/react-native-background-geolocation
Webkit is currently evaluating a Javascript-only solution. You can add your voice here
For a fully documented proof-of-concept example please see Brotkrumen.
The most popular RN geolocation library is https://github.com/react-native-geolocation/react-native-geolocation, and it supports this quite easily. I prefer this library over others because it automatically handles asking for permissions and such, and seems to have the simplest API.
Just do this:
Geolocation.watchPosition((position)=>{
const {latitude, longitude} = position.coords;
// Do something.
})
This requires no additional setup other than including the background modes fetch and location, and also the appropriate usage descriptions.
I find this more usable than Expo's API because it doesn't require any weird top level code and also doesn't require me to do anything other than create a watch position handler, which is really nice.
EDIT 2023!:
These days I would highly recommend using Expo's library instead of any of the other community libraries (mainly because our app started crashing when android got an OS update b/c of the lib I was using).
In fact, if you have to choose between expo and non expo library, always choose the expo library if only for the stability. Setting up expo's background location watching isn't super well documented but here's what I did to get it working in our app:
import { useEffect, useRef } from "react";
import * as Location from "expo-location";
import { LatLng } from "react-native-maps";
import * as TaskManager from "expo-task-manager";
import { LocationObject } from "expo-location";
import { v4 } from "uuid";
type Callback = (coords: LatLng) => void;
const BACKGROUND_TASK_NAME = "background";
const executor: (body: TaskManager.TaskManagerTaskBody<object>) => void = (
body
) => {
const data = body.data as unknown as { locations: LocationObject[] };
const l = data?.locations[0];
if (!l) return;
for (const callback of Object.values(locationCallbacks)) {
callback({
latitude: l.coords.latitude,
longitude: l.coords.longitude,
});
}
};
TaskManager.defineTask(BACKGROUND_TASK_NAME, executor);
const locationCallbacks: { [key: string]: Callback } = {};
const hasStartedBackgroundTaskRef = {
hasStarted: false,
};
function startBackgroundTaskIfNecessary() {
if (hasStartedBackgroundTaskRef.hasStarted) return;
Location.startLocationUpdatesAsync(BACKGROUND_TASK_NAME, {
accuracy: Location.Accuracy.Balanced,
}).catch((e) => {
hasStartedBackgroundTaskRef.hasStarted = false;
});
hasStartedBackgroundTaskRef.hasStarted = true;
}
function addLocationCallback(callback: Callback) {
const id = v4() as string;
locationCallbacks[id] = callback;
return {
remove: () => {
delete locationCallbacks[id];
},
};
}
export default function useLocationChangeListener(
callback: Callback | null,
active: boolean = true
) {
const callbackRef = useRef<null | Callback>(callback);
callbackRef.current = callback;
useEffect(() => {
if (!active) return;
if (!callback) return;
Location.getLastKnownPositionAsync().then((l) => {
if (l)
callback({
latitude: l.coords.latitude,
longitude: l.coords.longitude,
});
});
startBackgroundTaskIfNecessary();
const watch = Location.watchPositionAsync({}, (location) => {
callback({
latitude: location.coords.latitude,
longitude: location.coords.longitude,
});
});
const subscription = addLocationCallback(callback);
return () => {
subscription.remove();
watch.then((e) => {
e.remove();
});
};
}, [callback, active]);
useEffect(() => {
if (__DEV__) {
addLocationCallback((coords) => {
console.log("Location changed to ");
console.log(coords);
});
}
}, []);
}
You need to ask for background location permissions before this, BTW. Follow expos guide.
It's pretty risky trusting community libraries for stuff like this because of the fact that breaking android OS updates can happen at any moment and with open source maintainers they may or may not stay on top of it (you can more or less trust expo too, though)

React Navigation - How to access this.props.navigation in axios instance

I have an axios instance to set my baseURL and set the interceptors but everytime i want to use this.props.navigation i got an error undefined is not an object (this.props.navigation)
here's the code:
// Axios Setting
api.axiosInstance.interceptors.response.use((response)=>{
return response
}, (error) => {
if(error.response == undefined){
return Promise.reject(
Alert.alert("Perhatian","Tidak dapat terhubung ke server \n\n Cek koneksi internet anda",[
{text:"OK", onPress:()=>BackHandler.exitApp()}
])
)
} else if (error.response.status === 401) {
return Promise.reject(
goToLogin("Login", null)
);
}
})
//goToLogin Function on different js :
export function goToLogin(routeName, params){
return(
Alert.alert("Peringatan", "Sepertinya akun ini sudah login di perangkat lain\n\nsilahkan logout dan login kembali untuk dapat mengakses kembali",[
{text:'Logout', onPress:()=>{
console.log(this.props) // i got undefined on this line
// this.props.navigation.dispatch(
// NavigationActions.navigate({
// routeName:routeName,
// key:routeName,
// params:params
// })
// ),
// deleteAllUser()
}}
],{cancelable: false})
)
}
How can i access this.props.navigation when the component (axios) is not on screen?
Your problem is that you are trying to use the navigation prop from functions that are not React Components and probably don't have access to the navigation at all. In these cases, it's recommended to use a Navigation Service as described in the docs
Here is a simple example of how you can use it with axios interceptors to have a better understanding of what I'm suggesting:
https://snack.expo.io/BkLWor8FX
On App.js I make a GET call using axios to a non existent url like "https://www.google.coms". The interceptor will handle the failed request (Interceptors.js) and it will use the NavigationService(NavigationService.js) to redirect to the error screen.
I think you can use something similar in your case. Good luck!

Categories